0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

點(diǎn)陣字庫的原理及與矢量字庫的差別

電子設(shè)計(jì) ? 作者:電子設(shè)計(jì) ? 2018-09-23 10:01 ? 次閱讀

點(diǎn)陣字庫的生產(chǎn)原理

所有的漢字或者英文都是下面的原理,由左至右,每8個(gè)點(diǎn)占用一個(gè)字節(jié),最后不足8個(gè)字節(jié)的占用一個(gè)字節(jié),而且從最高位向最低位排列。

生成的字庫說明:(以12×12例子)

點(diǎn)陣字庫的原理及與矢量字庫的差別

一個(gè)漢字占用字節(jié)數(shù):12÷8=1····4也就是占用了2×12=24個(gè)字節(jié)。

編碼排序A0A0→A0FE A1A0→A2FE依次排列。

以12×12字庫的“我”為例:“我”的編碼為CED2,所以在漢字排在CEH-AOH=2EH區(qū)的D2H-A0H=32H個(gè)。所以在12×12字庫的起始位置就是[{FE-A0}*2EH+32H]*24=104976開始的24個(gè)字節(jié)就是我的點(diǎn)陣模。

其他的類推即可。

英文點(diǎn)陣也是如此推理。

在DOS程序中使用點(diǎn)陣字庫的方法

首先需要理解的是點(diǎn)陣字庫是一個(gè)數(shù)據(jù)文件,在這個(gè)數(shù)據(jù)文件里面保存了所有文字的點(diǎn)陣數(shù)據(jù)。至于什么是點(diǎn)陣,我想我不講大家都知道 的,使用過"文曲星"之類的電子辭典吧,那個(gè)的液晶顯示器上面顯示的漢子就能夠明顯的看出"點(diǎn)陣"的痕跡。在 PC 機(jī)上也是如此,文字也是由點(diǎn)陣來組成了,不同的是,PC機(jī)顯示器的顯示分辨率更高,高到了我們?nèi)庋蹮o法區(qū)分的地步,因此"點(diǎn)陣"的痕跡也就不那么明顯了。

點(diǎn)陣、矩陣、位圖這三個(gè)概念在本質(zhì)上是有聯(lián)系的,從某種程度上來講,這三個(gè)就是同義詞。點(diǎn)陣從本質(zhì)上講就是單色位圖,他使用一個(gè)比特來表示一個(gè)點(diǎn),如果這 個(gè)比特為0,表示某個(gè)位置沒有點(diǎn),如果為1表示某個(gè)位置有點(diǎn)。矩陣和位圖有著密不可分的聯(lián)系,矩陣其實(shí)是位圖的數(shù)學(xué)抽象,是一個(gè)二維的陣列。位圖就是這種 二維的陣列,這個(gè)陣列中的 (x,y) 位置上的數(shù)據(jù)代表的就是對(duì)原始圖形進(jìn)行采樣量化后的顏色值。但是,另一方面,我們要面對(duì)的問題是,計(jì)算機(jī)中數(shù)據(jù)的存放都是一維的,線性的。因此,我們需要 將二維的數(shù)據(jù)線性化到一維里面去。通常的做法就是將二維數(shù)據(jù)按行順序的存放,這樣就線性化到了一維。

那么點(diǎn)陣字的數(shù)據(jù)存放細(xì)節(jié)到底是怎么樣的呢。其實(shí)也十分的簡(jiǎn)單,舉個(gè)例子最能說明問題。比如說 16*16 的點(diǎn)陣,也就是說每一行有16個(gè)點(diǎn),由于一個(gè)點(diǎn)使用一個(gè)比特來表示,如果這個(gè)比特的值為1,則表示這個(gè)位置有點(diǎn),如果這個(gè)比特的值為0,則表示這個(gè)位置沒 有點(diǎn),那么一行也就需要16個(gè)比特,而8個(gè)比特就是一個(gè)字節(jié),也就是說,這個(gè)點(diǎn)陣中,一行的數(shù)據(jù)需要兩個(gè)字節(jié)來存放。第一行的前八個(gè)點(diǎn)的數(shù)據(jù)存放在點(diǎn)陣數(shù) 據(jù)的第一個(gè)字節(jié)里面,第一行的后面八個(gè)點(diǎn)的數(shù)據(jù)存放在點(diǎn)陣數(shù)據(jù)的第二個(gè)字節(jié)里面,第二行的前八個(gè)點(diǎn)的數(shù)據(jù)存放在點(diǎn)陣數(shù)據(jù)的第三個(gè)字節(jié)里面,…,然后后 面的就以此類推了。這樣我們可以計(jì)算出存放一個(gè)點(diǎn)陣總共需要32個(gè)字節(jié)??纯聪旅孢@個(gè)圖形化的例子:

點(diǎn)陣字庫的原理及與矢量字庫的差別

可以看出這是一個(gè)"漢"字的點(diǎn)陣,當(dāng)然文本的方式效果不是很好。根據(jù)上面的原則,我們可以寫出這個(gè)點(diǎn)陣的點(diǎn)陣數(shù) 據(jù):0x40,0x08,0x37,0xfc,0x10,0x08,…, 當(dāng)然寫這個(gè)確實(shí)很麻煩所以我不再繼續(xù)下去。我這樣做,也只是為了向你說明,在點(diǎn)陣字庫中,每一個(gè)點(diǎn)陣的數(shù)據(jù)就是按照這種方式存放的。

當(dāng)然也存在著不規(guī)則的點(diǎn)陣,這里說的不規(guī)則,指的是點(diǎn)陣的寬度不是8的倍數(shù),比如 12*12 的點(diǎn)陣,那么這樣的點(diǎn)陣數(shù)據(jù)又是如何存放的呢?其實(shí)也很簡(jiǎn)單,每一行的前面8個(gè)點(diǎn)存放在一個(gè)字節(jié)里面,每一行的剩下的4點(diǎn)就使用一個(gè)字節(jié)來存放,也就是說 剩下的4個(gè)點(diǎn)將占用一個(gè)字節(jié)的高4位,而這個(gè)字節(jié)的低4位沒有使用,全部都默認(rèn)的為零。這樣做當(dāng)然顯得有點(diǎn)浪費(fèi),不過卻能夠便于我們進(jìn)行存放和尋址。對(duì)于 其他不規(guī)則的點(diǎn)陣,也是按照這個(gè)原則進(jìn)行處理的。這樣我們可以得出一個(gè) m*n 的點(diǎn)陣所占用的字節(jié)數(shù)為 (m+7)/8*n.

在明白了以上所講的以后,我們可以寫出一個(gè)顯示一個(gè)任意大小的點(diǎn)陣字模的函數(shù),這個(gè)函數(shù)的功能是輸出一個(gè)寬度為w,高度為h的字模到屏幕的 (x,y) 坐標(biāo)出,文字的顏色為 color,文字的點(diǎn)陣數(shù)據(jù)為 pdata 所指:

/*輸出字模的函數(shù)*/

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

{

int i; /* 控制行 */

int j; /* 控制一行中的8個(gè)點(diǎn) */

int k; /* 一行中的第幾個(gè)"8個(gè)點(diǎn)"了 */

int nc; /* 到點(diǎn)陣數(shù)據(jù)的第幾個(gè)字節(jié)了 */

int cols; /* 控制列 */

BYTE static mask[8]={128, 64, 32, 16, 8, 4, 2, 1}; /* 位屏蔽字 */

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

nc = 0;

for (i=0; i

{

cols = 0;

for (k=0; k

{

for (j=0; j<8; j++)

{

if (pdata[nc]&mask[j])

putpixel(x+cols, y+i, color);

cols++;

}

nc++;

}

}

}

代碼很簡(jiǎn)單,不用怎么講解就能看懂,代碼可能不是最優(yōu)化的,但是應(yīng)該是最易讀懂的。其中的 putpixel 函數(shù),使用的是TC提供的 Graphics 中的畫點(diǎn)函數(shù)。使用這個(gè)函數(shù)就可以完成點(diǎn)陣任意大小的點(diǎn)陣字模的輸出。

接下來的問題就是如何在漢子庫中尋址某個(gè)漢子的點(diǎn)陣數(shù)據(jù)了。要解決這個(gè)問題,首先需要了解漢字在計(jì)算機(jī)中是如何表示的。在計(jì)算機(jī)中英文可以使用 ASCII 碼來表示,而漢字使用的是擴(kuò)展 ASCII 碼,并且使用兩個(gè)擴(kuò)展 ASCII 碼來表示一個(gè)漢字。一個(gè) ASCII 碼使用一個(gè)字節(jié)表示,所謂擴(kuò)展 ASCII 碼,也就是 ASCII 碼的最高位是1的 ASCII 碼,簡(jiǎn)單的說就是碼值大于等于 128 的 ASCII 碼。一個(gè)漢字由兩個(gè)擴(kuò)展 ASCII 碼組成,第一個(gè)擴(kuò)展 ASCII 碼用來存放區(qū)碼,第二個(gè)擴(kuò)展 ASCII 碼用來存放位碼。在 GB2312-80 標(biāo)準(zhǔn)中,將所有的漢字分為94個(gè)區(qū),每個(gè)區(qū)有94個(gè)位可以存放94個(gè)漢字,形成了人們常說的區(qū)位碼,這樣總共就有 94*94=8836 個(gè)漢字。在點(diǎn)陣字庫中,漢字點(diǎn)陣數(shù)據(jù)就是按照這個(gè)區(qū)位的順序來存放的,也就是最先存放的是第一個(gè)區(qū)的漢字點(diǎn)陣數(shù)據(jù),在每一個(gè)區(qū)中有是按照位的順序來存放 的。在漢字的內(nèi)碼中,漢字區(qū)位碼的存放實(shí)在擴(kuò)展 ASCII 基礎(chǔ)上存放的,并且將區(qū)碼和位碼都加上了32,然后存放在兩個(gè)擴(kuò)展 ASCII 碼中。具體的說就是:

第一個(gè)擴(kuò)展ASCII碼 = 128+32 + 漢字區(qū)碼

第二個(gè)擴(kuò)展ASCII嗎 = 128+32 + 漢字位碼

如果用char hz[2]來表示一個(gè)漢字,那么我可以計(jì)算出這個(gè)漢字的區(qū)位碼為:

區(qū)碼 = hz[0] - 128 - 32 = hz[0] - 160

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

這樣,我們可以根據(jù)區(qū)位碼在文件中進(jìn)行殉職了,尋址公式如下:

漢字點(diǎn)陣數(shù)據(jù)在字庫文件中的偏移 = ((區(qū)碼-1) * 94 + 位碼) * 一個(gè)點(diǎn)陣字模占用的字節(jié)數(shù)

在尋址以后,即可讀取漢字的點(diǎn)陣數(shù)據(jù)到緩沖區(qū)進(jìn)行顯示了。以下是實(shí)現(xiàn)代碼:

/* 輸出一個(gè)漢字的函數(shù) */

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

{

char fontbuf[128]; /* 足夠大的緩沖區(qū),也可以動(dòng)態(tài)分配 */

int ch0 = (BYTE)hz[0]-0xA0; /* 區(qū)碼 */

int ch1 = (BYTE)hz[1]-0xA0; /* 位碼 */

/* 計(jì)算偏移 */

long offset = (long)pf->_hz_buf_size * ((ch0 - 1) * 94 + ch1 - 1);

fseek(fp, offset, SEEK_SET); /* 進(jìn)行尋址 */

fread(fontbuf, 1, (w + 7) / 8 * h, fp); /* 讀入點(diǎn)陣數(shù)據(jù) */

_draw_model(fontbuf, w, h, x, y, color); /* 繪制字模 */

}

以上介紹完了中文點(diǎn)陣字庫的原理,當(dāng)然還有英文點(diǎn)陣字庫了。英文點(diǎn)陣字庫中單個(gè)點(diǎn)陣字模數(shù)據(jù)的存放方式與中文是一模一樣的,也就是對(duì)我們所寫的 _draw_model 函數(shù)同樣可以使用到英文字庫中。唯一不同的是對(duì)點(diǎn)陣字庫的尋址上。英文使用的就是 ASCII 碼,其碼值是0到127,尋址公式為:

英文點(diǎn)陣數(shù)據(jù)在英文點(diǎn)陣字庫中的偏移 = 英文的ASCII碼 * 一個(gè)英文字模占用的字節(jié)數(shù)

可以看到,區(qū)分中英文的關(guān)鍵就是,一個(gè)字符是 ASCII 碼還是擴(kuò)展 ASCII 碼,如果是 ASCII 碼,其范圍是0到127,這樣是使用的英文字庫,如果是擴(kuò)展 ASCII 碼,則與其后的另一個(gè)擴(kuò)展 ASCII 碼組成漢字內(nèi)碼,使用中文字庫進(jìn)行顯示。只要正確區(qū)分 ASCII 碼的類型并進(jìn)行分別的處理,也就能實(shí)現(xiàn)中英文字符串的混合輸出了。

點(diǎn)陣字庫和矢量字庫的差別

我們都只知道,各種字符在電腦屏幕上都是以一些點(diǎn)來表示的,因此也叫點(diǎn)陣。最早的字庫就是直接把這些點(diǎn)存儲(chǔ)起來,就是點(diǎn)陣字庫。常見的漢字點(diǎn)陣字庫有 16x16, 24x24 等。點(diǎn)陣字庫也有很多種,主要區(qū)別在于其中存儲(chǔ)編碼的方式不同。點(diǎn)陣字庫的最大缺點(diǎn)就是它是固定分辨率的,也就是每種字庫都有固定的大小尺寸,在原始尺寸下使用,效果很好,但如果將其放大或縮小使用,效果就很糟糕了,就會(huì)出現(xiàn)我們通常說的鋸齒現(xiàn)象。因?yàn)樾枰淖煮w大小組合有無數(shù)種,我們也不可能為每種大小都定義一個(gè)點(diǎn)陣字庫。于是就出現(xiàn)了矢量字庫。

矢量字庫

矢量字庫是把每個(gè)字符的筆劃分解成各種直線和曲線,然后記下這些直線和曲線的參數(shù),在顯示的時(shí)候,再根據(jù)具體的尺寸大小,畫出這些線條,就還原了原來的字符。它的好處就是可以隨意放大縮小而不失真。而且所需存儲(chǔ)量和字符大小無關(guān)。矢量字庫有很多種,區(qū)別在于他們采用的不同數(shù)學(xué)模型來描述組成字符的線條。常見的矢量字庫有 Type1字庫和Truetype字庫。

在點(diǎn)陣字庫中,每個(gè)字符由一個(gè)位圖表示,并把它用一個(gè)稱為字符掩膜的矩陣來表示,其中的每個(gè)元素都是一位二進(jìn)制數(shù),如果該位為1表示字符的筆畫經(jīng)過此位,該像素置為字符顏色;如果該位為0,表示字符的筆畫不經(jīng)過此位,該像素置為背景顏色。點(diǎn)陣字符的顯示分為兩步:首先從字庫中將它的位圖檢索出來,然后將檢索到的位圖寫到幀緩沖器中。

在實(shí)際應(yīng)用中,同一個(gè)字符有多種字體(如宋體、楷體等),每種字體又有多種大小型號(hào),因此字庫的存儲(chǔ)空間十分龐大。為了減少存儲(chǔ)空間,一般采用壓縮技術(shù)。

矢量字符記錄字符的筆畫信息而不是整個(gè)位圖,具有存儲(chǔ)空間小,美觀、變換方便等優(yōu)點(diǎn)。例如:在AutoCAD中使用圖形實(shí)體-形(Shape)-來定義矢量字符,其中,采用了直線和圓弧作為基本的筆畫來對(duì)矢量字符進(jìn)行描述。 對(duì)于字符的旋轉(zhuǎn)、放大、縮小等幾何變換,點(diǎn)陣字符需要對(duì)其位圖中的每個(gè)象素進(jìn)行變換,而矢量字符則只需要對(duì)其幾何圖素進(jìn)行變換就可以了,例如:對(duì)直線筆畫的兩個(gè)端點(diǎn)進(jìn)行變換,對(duì)圓弧的起點(diǎn)、終點(diǎn)、半徑和圓心進(jìn)行變換等等。

矢量字符的顯示也分為兩步。首先從字庫中將它的字符信息。然后取出端點(diǎn)坐標(biāo),對(duì)其進(jìn)行適當(dāng)?shù)膸缀巫儞Q,再根據(jù)各端點(diǎn)的標(biāo)志顯示出字符。

輪廓字形法是當(dāng)今國(guó)際上最流行的一種字符表示方法,其壓縮比大,且能保證字符質(zhì)量。輪廓字形法采用直線、B樣條/Bezier曲線的集合來描述一個(gè)字符的輪廓線。輪廓線構(gòu)成一個(gè)或若干個(gè)封閉的平面區(qū)域。輪廓線定義加上一些指示橫寬、豎寬、基點(diǎn)、基線等等控制信息就構(gòu)成了字符的壓縮數(shù)據(jù)。

如何使用Windows的系統(tǒng)字庫生成點(diǎn)陣字庫?

我的程序現(xiàn)在只能預(yù)覽一個(gè)漢字的不同字體的點(diǎn)陣表達(dá)。

界面很簡(jiǎn)單: 一個(gè)輸出點(diǎn)陣大小的選擇列表(8x8,16x16,24x24等),一個(gè)系統(tǒng)中已有的字體名稱列表,一個(gè)預(yù)覽按鈕,一塊畫圖顯示區(qū)域。

得到字體列表的方法:(作者稱這一段是用來取回系統(tǒng)的字體,然后添加到下拉框中)

//取字體名稱列表的回調(diào)函數(shù),使用前要聲明一下該方法

int CALLBACK MyEnumFontProc(ENUMLOGFONTEX* lpelf,NEWTEXTMETRICEX* lpntm,DWORD nFontType,long lParam)

{

CFontPeekerDlg* pWnd=(CFontPeekerDlg*) lParam;

if(pWnd)

{

if( pWnd->m_combo_sfont.FindString(0, lpelf->elfLogFont.lfFaceName) <0 )

pWnd->m_combo_sfont.AddString(lpelf->elfLogFont.lfFaceName);

return 1;

}

return 0;

}

//說明:CFontPeekerDlg 是我的dialog的類名, m_combo_sfont是列表名稱下拉combobox關(guān)聯(lián)的control變量

//調(diào)用的地方 (******問題1:下面那個(gè)&lf怎么得到呢……)

{

::EnumFontFamiliesEx((HDC) dc,&lf, (FONTENUMPROC)MyEnumFontProc,(LPARAM) this,0);

m_combo_sfont.SetCurSel(0);

}

字體預(yù)覽:

如果點(diǎn)陣大小選擇16,顯示的時(shí)候就畫出16x16個(gè)方格。自定義一個(gè)類CMyStatic繼承自CStatic,用來畫圖。在CMyStatic的OnPaint()函數(shù)中計(jì)算并顯示。

取得字體:

常用的方法:用CreateFont創(chuàng)建字體,把字TextOut再用GetPixel()取點(diǎn)存入數(shù)組。 缺點(diǎn):必須把字TextOut出來,能在屏幕上看見,不爽。

我的方法,用這個(gè)函數(shù):GetGlyphOutline(),可以得到一個(gè)字的輪廓矢量或者位圖。可以不用textout到屏幕,直接取得字模信息

函數(shù)原型如下:

DWORD GetGlyphOutline(

HDC hdc, //畫圖設(shè)備句柄

UINT uChar, //將要讀取的字符/漢字

UINT uFormat, //返回?cái)?shù)據(jù)的格式(字的外形輪廓還是字的位圖)

LPGLYPHMETRICS lpgm, // GLYPHMETRICS結(jié)構(gòu)地址,輸出參數(shù)

DWORD cbBuffer, //輸出數(shù)據(jù)緩沖區(qū)的大小

LPVOID lpvBuffer, //輸出數(shù)據(jù)緩沖區(qū)的地址

CONST MAT2 *lpmat2 //轉(zhuǎn)置矩陣的地址

);

說明:

uChar字符需要判斷是否是漢字還是英文字符。中文占2個(gè)字節(jié)長(zhǎng)度。

lpgm是輸出函數(shù),調(diào)用GetGlyphOutline()是無須給lpgm 賦值。

lpmat2如果不需要轉(zhuǎn)置,將 eM11.value=1; eM22.value=1; 即可。

cbBuffer緩沖區(qū)的大小,可以先通過調(diào)用GetGlyphOutline(……lpgm, 0, NULL, mat); 來取得,然后動(dòng)態(tài)分配lpvBuffer,再一次調(diào)用GetGlyphOutline,將信息存到lpvBuffer. 使用完畢后再釋放lpvBuffer.

程序示例:(***問題2:用這段程序,我獲取的字符點(diǎn)陣總都是一樣的,不管什么字……)

……前面部分省略……

GLYPHMETRICS glyph;

MAT2 m2;

memset(&m2, 0, sizeof(MAT2));

m2.eM11.value = 1;

m2.eM22.value = 1;

//取得buffer的大小

DWORD cbBuf = dc.GetGlyphOutline( nChar, GGO_BITMAP, &glyph, 0L, NULL, &m2);

BYTE* pBuf=NULL;

//返回GDI_ERROR表示失敗。

if( cbBuf != GDI_ERROR )

{

pBuf = new BYTE[cbBuf];

//輸出位圖GGO_BITMAP 的信息。輸出信息4字節(jié)(DWORD)對(duì)齊

dc.GetGlyphOutline( nChar, GGO_BITMAP, &glyph, cbBuf, pBuf, &m2);

}

else

{

if(m_pFont!=NULL)

delete m_pFont;

return;

}

編程中遇到問題:

一開始,GetGlyphOutline總是返回-1,getLastError顯示是"無法完成的功能",后來發(fā)現(xiàn)是因?yàn)檎{(diào)用之前沒有給hdc設(shè)置Font.

后來能取得pBuf信息后,又開始郁悶,因?yàn)椴惶靼譩itmap的結(jié)果是按什么排列的。后來跟蹤漢字"一"來調(diào)試(這個(gè)字簡(jiǎn)單),注意到了glyph.gmBlackBoxX 其實(shí)就是輸出位圖的寬度,glyph.gmBlackBoxY就是高度。如果gmBlackBoxX=15,glyph.gmBlackBoxY=2,表示輸出的pBuf中有這些信息:位圖有2行信息,每一行使用15 bit來存儲(chǔ)信息。

例如:我讀取"一":glyph.gmBlackBoxX = 0x0e,glyph.gmBlackBoxY=0x2; pBuf長(zhǎng)度cbBuf=8 字節(jié)

pBuf信息: 00 08 00 00 ff fc 00 00

字符寬度 0x0e=14 則 第一行信息為: 0000 0000 0000 100 (只取到前14位)

第二行根據(jù)4字節(jié)對(duì)齊的規(guī)則,從0xff開始 1111 1111 1111 110

看出"一"字了嗎?呵呵

直到他的存儲(chǔ)之后就可以動(dòng)手解析輸出的信息了。

我定義了一個(gè)宏#define BIT(n) (1《(n)) 用來比較每一個(gè)位信息時(shí)使用

后來又遇到了一個(gè)問題,就是小頭和大頭的問題了。在我的機(jī)器上是little endian的形式,如果我用

unsigned long *lptr = (unsigned long*)pBuf;

//j from 0 to 15

if( *lptr & BIT(j) )

{

//這時(shí)候如果想用j來表示寫1的位數(shù),就錯(cuò)了

}

因?yàn)閺淖止?jié)數(shù)組中轉(zhuǎn)化成unsigned long型的時(shí)候,數(shù)值已經(jīng)經(jīng)過轉(zhuǎn)化了,像上例中,實(shí)際上是0x0800 在同BIT(j)比較。

不多說了,比較之前轉(zhuǎn)化一下就可以了if( htonl(*lptr) & BIT(j) )

Unicode中文點(diǎn)陣字庫的生成與使用

點(diǎn)陣字庫包含兩部分信息。首先是點(diǎn)陣字庫文件頭信息,它包含點(diǎn)陣字庫文字的字號(hào)、多少位表示一個(gè)像素,英文字母與符號(hào)的size、起始和結(jié)束unicode編碼、在文件中的起始偏移,漢字的size、起始和結(jié)束unicode編碼、在文件中的起始偏移。然后是真實(shí)的點(diǎn)陣數(shù)據(jù),即一段段二進(jìn)制串,每一串表示一個(gè)字母、符號(hào)或漢字的點(diǎn)陣信息。

要生成點(diǎn)陣字庫必須有文字圖形的,我的方法是使用ttf字體。ttf字體的顯示采用的是SDL_ttf庫,這是開源圖形庫SDL的一個(gè)擴(kuò)展庫,它使用的是libfreetype以讀取和繪制ttf字體。

它提供了一個(gè)函數(shù),通過傳入一個(gè)Unicode編碼便能輸出相應(yīng)的文字的帶有alpha通道的位圖。那么我們可以掃描這個(gè)位圖以得到相應(yīng)文字的點(diǎn)陣信息。由于帶有alpha通道,我們可以在點(diǎn)陣信息中也加入權(quán)值,使得點(diǎn)陣字庫也有反走樣效果。我采用兩位來表示一個(gè)點(diǎn),這樣會(huì)有三級(jí)灰度(還有一個(gè)表示透明)。

點(diǎn)陣字庫的顯示首先需要將文件頭信息讀取出來,然后根據(jù)unicode編碼判斷在哪個(gè)區(qū)間內(nèi),然后用unicode編碼減去此區(qū)間的起始unicode編碼,算出相對(duì)偏移,并加上此區(qū)間的文件起始偏移得到文件的絕對(duì)偏移,然后讀出相應(yīng)位數(shù)的數(shù)據(jù),最后通過掃描這段二進(jìn)制串,在屏幕的相應(yīng)位置輸出點(diǎn)陣字型。

顯示點(diǎn)陣字體需要頻繁讀取文件,因此最好做一個(gè)固定大小的緩存,采用LRU置換算法維護(hù)此緩存,以減少磁盤讀取。

標(biāo)準(zhǔn)點(diǎn)陣字庫芯片

標(biāo)準(zhǔn)點(diǎn)陣字庫芯片的特點(diǎn):

1.內(nèi)涵全國(guó)信標(biāo)委授權(quán)的標(biāo)準(zhǔn)點(diǎn)陣字型數(shù)據(jù)、

2.支持國(guó)標(biāo)字符集GB2312(6,763漢字),GB18030(27,484漢字)。

3.支持多種點(diǎn)陣字型,包括11×12點(diǎn),15×16點(diǎn),24×24點(diǎn),32×32點(diǎn)。

4.免除了字庫燒錄和測(cè)試工序,并節(jié)省了2%以上的燒錄損耗。

5.價(jià)格相當(dāng)于空白FLASH價(jià)格

標(biāo)準(zhǔn)點(diǎn)陣字庫芯片的種類和應(yīng)用

標(biāo)準(zhǔn)點(diǎn)陣漢字字庫芯片

1 概述

GT23L24M1W是一款內(nèi)含24X24點(diǎn)陣的漢字庫芯片,支持GB18030國(guó)標(biāo)漢字(含有國(guó)家信標(biāo)委合法授權(quán))及ASCII字符,排列格式為橫置橫排,用戶通過字符內(nèi)碼,利用本手冊(cè)提供的方法計(jì)算出該字符點(diǎn)陣在芯片中的地址,可從該地址連續(xù)讀出字符點(diǎn)陣信息。

1.1 芯片特點(diǎn)

● 數(shù)據(jù)總線:

SPI 串行總線接口

PLII 精簡(jiǎn)地址并行總線接口

● 點(diǎn)陣排列方式:字節(jié)橫置橫排

● 訪問速度:

SPI 時(shí)鐘頻率:20MHz(max.)

PLII 訪問速度:130ns(max.)@3.3V

● 工作電壓:2.7V~3.6V

電流

工作電流:12mA

待機(jī)電流:10uA

● 封裝:SO20W

● 尺寸(SO20W):12.80mmX10.30mm

● 工作溫度:-20℃~85℃(SPI 模式下);-10℃~85℃(PLII 模式下)

點(diǎn)陣字庫的原理及與矢量字庫的差別

1.2 字庫內(nèi)容

點(diǎn)陣字庫的原理及與矢量字庫的差別

字型樣張

2 引腳描述與接口連接

2.1 引腳名稱

2.2 SPI 接口引腳描述

串行數(shù)據(jù)輸出(SO):該信號(hào)用來把數(shù)據(jù)從芯片串行輸出,數(shù)據(jù)在時(shí)鐘的下降沿移出。

串行數(shù)據(jù)輸入(SI):該信號(hào)用來把數(shù)據(jù)從串行輸入芯片,數(shù)據(jù)在時(shí)鐘的上升沿移入。

串行時(shí)鐘輸入(SCLK):數(shù)據(jù)在時(shí)鐘上升沿移入,在下降沿移出。

片選輸入(CS#):所有串行數(shù)據(jù)傳輸開始于CE#下降沿,CE#在傳輸期間必須保持為低電平,在兩條

指令之間保持為高電平。

總線掛起輸入(HOLD#):

2.3 SPI 接口與主機(jī)接口電路示意圖

SPI 與主機(jī)接口電路連接可以參考下圖(#HOLD管腳建議接 2K 電阻 3.3V 拉高)。

若是采用系統(tǒng)電壓為 5V的,則需要進(jìn)行電平轉(zhuǎn)換匹配連接 GT23 芯片,可以參考下圖(#HOLD 管腳建議接 2K 電阻 3.3V 拉高)。

2.4 PLII 接口引腳描述

2.5 PLII 接口與主機(jī)接口電路示意圖

SPI/PLII_SEL(管腳內(nèi)部有 100K 上拉電阻)接地,字庫芯片選擇 PLII 接口模式,與主機(jī)接口電路連接可以參考下圖。

2.6 PLII 總線接口尋址說明

在 PLII 總線模式下,芯片內(nèi)部有 3個(gè)地址寄存器,主機(jī)需要把要讀取數(shù)據(jù)的地址寫入這 3個(gè)地址寄存器,然后再?gòu)臄?shù)據(jù)寄存器中讀出數(shù)據(jù)。主機(jī)每讀一次數(shù)據(jù)寄存器,芯片內(nèi)部的地址寄存器會(huì)自動(dòng)增一,從而使主機(jī)只寫一次首地址,就可以連續(xù)讀取數(shù)據(jù)。

3 字庫調(diào)用方法

3.1 漢字點(diǎn)陣排列格式

每個(gè)漢字在芯片中是以漢字點(diǎn)陣字模的形式存儲(chǔ)的,每個(gè)點(diǎn)用一個(gè)二進(jìn)制位表示,存 1的點(diǎn),當(dāng)顯示

時(shí)可以在屏幕上顯示亮點(diǎn),存 0的點(diǎn),則在屏幕上不顯示。點(diǎn)陣排列格式為橫置橫排:即一個(gè)字節(jié)的高位

表示左面的點(diǎn),低位表示右面的點(diǎn)(如果用戶按 word mode讀取點(diǎn)陣數(shù)據(jù),請(qǐng)注意高低字節(jié)的順序),排

滿一行的點(diǎn)后再排下一行。這樣把點(diǎn)陣信息用來直接在顯示器上按上述規(guī)則顯示,則將出現(xiàn)對(duì)應(yīng)的漢字。

3.1.1 24X24點(diǎn)漢字排列格式

24X24 點(diǎn)漢字的信息需要 72個(gè)字節(jié)(BYTE 0 – BYTE 71)來表示。該 24X24 點(diǎn)漢字的點(diǎn)陣數(shù)據(jù)是橫置橫排的,其具體排列結(jié)構(gòu)如下圖:

命名規(guī)則:

最大字符集及字?jǐn)?shù)

S:GB2312 6,763漢字

M:GB18030 27,484漢字

T:GB12345 6,866漢字

BIG5 5,401 / 13,060漢字

U:Unicode V3.0 27,484漢字

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • ASCII
    +關(guān)注

    關(guān)注

    5

    文章

    172

    瀏覽量

    35024
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4290

    瀏覽量

    62342
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4730

    瀏覽量

    68259
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)專業(yè)提供以下產(chǎn)品:1、適用于MTK平臺(tái)矢量引擎及多款矢量字庫2、適用于MTK平臺(tái)的平滑
    發(fā)表于 07-22 10:28

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)專業(yè)提供以下產(chǎn)品:1、適用于MTK平臺(tái)矢量引擎及多款矢量字庫2、適用于MTK平臺(tái)的平滑
    發(fā)表于 07-22 10:28

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)專業(yè)提供以下產(chǎn)品:1、適用于MTK平臺(tái)矢量引擎及多款矢量字庫2、適用于MTK平臺(tái)的平滑
    發(fā)表于 07-29 15:15

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)專業(yè)提供以下產(chǎn)品:1、適用于MTK平臺(tái)矢量引擎及多款矢量字庫2、適用于MTK平臺(tái)的平滑
    發(fā)表于 08-05 10:45

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)專業(yè)提供以下產(chǎn)品:1、適用于MTK平臺(tái)矢量引擎及多款矢量字庫2、適用于MTK平臺(tái)的平滑
    發(fā)表于 08-07 10:09

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)專業(yè)提供以下產(chǎn)品:1、適用于MTK平臺(tái)矢量引擎及多款矢量字庫2、適用于MTK平臺(tái)的平滑
    發(fā)表于 08-12 09:53

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)專業(yè)提供以下產(chǎn)品:1、適用于MTK平臺(tái)矢量引擎及多款矢量字庫2、適用于MTK平臺(tái)的平滑
    發(fā)表于 08-25 10:56

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)

    專業(yè)提供適用于MTK平臺(tái)的矢量引擎、矢量字庫、輸入法(支持多國(guó)語言)專業(yè)提供以下產(chǎn)品:1、適用于MTK平臺(tái)矢量引擎及多款矢量字庫2、適用于MTK平臺(tái)的平滑
    發(fā)表于 03-29 14:23

    高通多字號(hào)字體點(diǎn)陣字庫解決方案

    多年來隨著IT產(chǎn)業(yè)的日新月異,高通一直堅(jiān)持發(fā)展中文信息產(chǎn)品,開發(fā)多款標(biāo)準(zhǔn)點(diǎn)陣字庫芯片、外文點(diǎn)陣字庫芯片以及矢量字庫芯片。無論電子產(chǎn)品如何升級(jí)換代,漢字信息處理永遠(yuǎn)是信息終端產(chǎn)品的剛性需求。通過不斷地
    發(fā)表于 05-05 14:25

    高通多字號(hào)字體點(diǎn)陣字庫解決方案

    多年來隨著IT產(chǎn)業(yè)的日新月異,高通一直堅(jiān)持發(fā)展中文信息產(chǎn)品,開發(fā)多款標(biāo)準(zhǔn)點(diǎn)陣字庫芯片、外文點(diǎn)陣字庫芯片以及矢量字庫芯片。無論電子產(chǎn)品如何升級(jí)換代,漢字信息處理永遠(yuǎn)是信息終端產(chǎn)品的剛性需求。通過不斷地
    發(fā)表于 05-05 14:25

    使用UCDOS的點(diǎn)陣字庫

    1 引 言  單片機(jī)控制的LED、LCD顯示屏均涉及到各種字體的漢字顯示。建立單片機(jī)漢字字庫的傳統(tǒng)方法有使用硬件字庫或者使用UCDOS的點(diǎn)陣字庫。這些字庫均非
    發(fā)表于 11-18 06:05

    矢量字庫在嵌入式機(jī)頂盒中的應(yīng)用

    介紹嵌入式數(shù)字衛(wèi)星接收機(jī)的字符顯示原理。提出一種提取Windows矢量字庫信息以及將其轉(zhuǎn)換為點(diǎn)陣字庫格式的方法。給出主要模塊的流程圖和VC程序?qū)崿F(xiàn)。在DVB-S接收機(jī)頂盒系統(tǒng)中的
    發(fā)表于 05-16 14:47 ?18次下載

    高通矢量字庫解決方案 — 16點(diǎn)陣字庫至192點(diǎn)陣的字號(hào)

    ,導(dǎo)致無法正常識(shí)別文字信息等一系問題。方案特點(diǎn):? ? ? ?1、采用高通矢量字庫算法,支持16點(diǎn)陣字庫至192點(diǎn)陣的字號(hào);? ? ? ?2、支持宋體、黑體、仿宋、楷體等中文;? ? ? ?3、支持文字
    發(fā)表于 10-31 22:43 ?2508次閱讀
    高通<b class='flag-5'>矢量字庫</b>解決方案 —  16<b class='flag-5'>點(diǎn)陣字庫</b>至192<b class='flag-5'>點(diǎn)陣</b>的字號(hào)

    單片機(jī)巧用Windows矢量字庫

    1 引 言  單片機(jī)控制的LED、LCD顯示屏均涉及到各種字體的漢字顯示。建立單片機(jī)漢字字庫的傳統(tǒng)方法有使用硬件字庫或者使用UCDOS的點(diǎn)陣字庫。這些字庫均非
    發(fā)表于 11-11 15:06 ?6次下載
    單片機(jī)巧用Windows<b class='flag-5'>矢量字庫</b>

    顯示屏點(diǎn)陣字庫

    顯示屏點(diǎn)陣字庫
    發(fā)表于 04-06 09:19 ?7次下載