※點(diǎn)陣漢字顯示原理及其在點(diǎn)陣 LCD&LED 中的應用※ 發(fā)表時(shí)間:2007-3-18 10:03:48 天氣狀況:
心情指數:
瀏覽次數:145
本文由豪智軟件工具自由職業(yè)者 秦文豪 提供 下載本文
摘要: 本文主要論述漢字的顯示原理,并詳細闡述了如何創(chuàng )建點(diǎn)陣字庫,如何在點(diǎn)陣 LCD&LED 進(jìn)行掃描顯示的原理,還闡述了如何根據不同的字符編碼標準,來(lái)存取數據,使您的系統可以和計算機兼容,并象計算機一樣能顯示各種字符。
關(guān)鍵字: 位( bit )、字節( byte )、字模、計算機內碼( ASCII )、 UNICODE 編碼
提示: 如果沒(méi)有特別提示,本文所提到的字庫都是指點(diǎn)陣字庫
問(wèn)題引入
大千世界中,有很多物質(zhì)都可以看作是由很小很小的點(diǎn)(例如:分子、原子)組成的,當然,您所看到的字符也不例外。假設我們把一個(gè)字符分成若干個(gè)可視的點(diǎn)組成,換句話(huà)來(lái)說(shuō),就是一個(gè)個(gè)點(diǎn)組成了我們看到的字符。假設您的電腦顯示器是液晶的,您不妨仔細的看看,每一個(gè)字符或圖形都是由一個(gè)個(gè)的點(diǎn)組成的,只是這些點(diǎn)很小,小得讓您不容易發(fā)現而已(仔細看看還是不難發(fā)現呀?。?;由此,我們引入點(diǎn)陣字符的概念,從微觀(guān)的電子信號 0 或 1 ,到宏觀(guān)可視的字符,足以讓我們感嘆這世界真是豐富多彩,奧妙無(wú)窮??!
字模數據
首先,從我們常用的計算機系統談起,再擴展到我們要開(kāi)發(fā)設計的點(diǎn)陣 LCD&LED顯示系統中去,其實(shí)單片機系統的顯示原理和計算機是一樣的。在計算機中,所有的數據(包括指令等)都是以 0 和 1來(lái)表示的,這意味著(zhù),如果我們想要在顯示器上顯示字符,那么這些字符的信息將也會(huì )是以 0 、 1來(lái)保存顯示的。那么計算機是如何來(lái)存貯顯示字符的呢?下面我們舉例來(lái)說(shuō)明點(diǎn)陣字符的數據存貯及顯示原理(這里我們主要討論的是點(diǎn)陣字符,故有關(guān)計算機矢量字符的顯示及其原理這里就不作說(shuō)明,而且單片機的尋址和計算能力遠不及 PC,故顯示矢量的字符還是有一定的困難)。假設我們把計算機液晶顯示器上顯示 16x16 點(diǎn)陣的“豪”字放大 10 倍,如下圖所示:
放大 10 倍的“豪” 位信息 字模數據
放大之后,每一個(gè)小方格代表一個(gè)點(diǎn),黑色的為 1 ,白色為 0 ;每一個(gè)點(diǎn)看作為一位( bit )。據此可以描繪出“豪”字的位( bit)信息。采用行掃描的方式,每八位( bit)為一個(gè)字節,這里采用十六進(jìn)制表示,這樣就得到了字模數據。由上述的示例,我們可以清晰的了解到可視字符、位信息與字模數據之間的關(guān)系。清楚了上面的關(guān)系之后,我們就可以自己編寫(xiě)一個(gè)字模數據生成工具了。筆者自己就編寫(xiě)了兩款很強勁的字模工具(漢字字模點(diǎn)陣數據批量生成工具[下載]和 Font Model Tool,前者是針對漢字編寫(xiě)的,后來(lái)一小日本想用這個(gè)工具,Font Model Tool就出生了,不過(guò)新增了很多功能,而且是一個(gè)中英文可以互相切換的雙語(yǔ)版 ),這里介紹給大家,希望共同學(xué)習和使用喲。
[點(diǎn)陣異常處理]假設字符的點(diǎn)陣不是 8 的倍數怎么辦呢?通常情況下可以不計或在后面以 4 個(gè) 0 位補足 8 位都可,例如: 12x12點(diǎn)陣的漢字,以本人編寫(xiě)的字模工具軟件 為例,是這樣處理的:先假設對12x12的點(diǎn)陣字符進(jìn)行掃描,第一行的前8位為一個(gè)字節,第一行的后面4位形成一個(gè)字節,以后的每行逐次類(lèi)推,直到掃描到最后一行,行成一個(gè)完整可用的字模數據。
點(diǎn)陣字庫
把上述很多很多字符的字模數據按照一定的排列順序存放在一起,就形成了點(diǎn)陣字庫。這里所講的字庫是廣義的,可以是文件,也可以是其他的東東,例如:數組、 DB 表等等所有可以存取數據的形式。有的點(diǎn)陣字庫還帶有索引表,用來(lái)方便程序的編寫(xiě)及查詢(xún)。
在計算機中如何顯示一個(gè)字符
在計算機中是如何把點(diǎn)陣字符顯示出來(lái)的呢?其實(shí)字符的顯示過(guò)程是字模數據創(chuàng )建的逆過(guò)程。首先我們要明白字模數據的排列掃描方式,然后再把 16進(jìn)制的字模數據變成位( bit)信息,最后才能根據位信息按照字模數據給定的掃描方式逐個(gè)把點(diǎn)描繪出來(lái)。光說(shuō)還是不行的,最好我們親自動(dòng)手來(lái)實(shí)驗一下,先假定我們要用行掃描的顯示方式,在計算機中顯示一個(gè)“豪”字,我們可以使用字模軟件來(lái)創(chuàng )建一個(gè)字模數據,設定為行掃描、 16x16 點(diǎn)陣、宋體、 11 號字,創(chuàng )建如下字模數據:
unsigned char hao0[]={
0x00,0x00, 0x00,0x80, 0x3F,0xFC, 0x00,0x00,
0x07,0xF0, 0x04,0x10, 0x3F,0xFE, 0x20,0x02,
0x4F,0xF4, 0x05,0x20, 0x1A,0xC0, 0x04,0xA0,
0x1B,0x58, 0x04,0x46, 0x19,0x80, 0x00,0x00
};
則 C 語(yǔ)言全部顯示代碼描述如下:
unsigned char cmp_w[8]={128,64,32,16,8,4,2,1}; // 用于取位
unsigned char hao0[]={ /* 字模數組 */
0x00,0x00, 0x00,0x80, 0x3F,0xFC, 0x00,0x00,
0x07,0xF0, 0x04,0x10, 0x3F,0xFE, 0x20,0x02,
0x4F,0xF4, 0x05,0x20, 0x1A,0xC0, 0x04,0xA0,
0x1B,0x58, 0x04,0x46, 0x19,0x80, 0x00,0x00
};
void FontDisplay(int x, int y, unsigned char * FontModule) ; /*16x16 單個(gè)字符行掃描函數 */
void FontDisplay(int x, int y, unsigned char * FontModule)
{/*x: 水平偏移坐標, y: 垂直偏移坐標 */
for(int row=0;row<16;row++)
{
for(int c=0;c<8;c++)
if((FontModule[row*2]&cmp_w[c])!=0)
putpixel(c+x,row+y,15);/* 畫(huà)一個(gè)點(diǎn) */
for(c=0;c<8;c++)
if((FontModule[row*2+1]&cmp_w[c])!=0)
putpixel(c+8+x,row+y,15);
}
} main()
{/* 調用顯示主程序 */
FontDisplay(5,5, hao0 );
}
上述代碼直接拷貝即可用,假設你的系統需要顯示的字符不多,直接使用上面的代碼或稍做修改,直接編譯燒寫(xiě)到芯片里,即可滿(mǎn)足一般點(diǎn)陣字符顯示的需求,而不需要制作大的文件字庫,節省有限的 ROM 空間,編程又極其簡(jiǎn)單。假設我們要顯示一串字符,把這一串字符拷貝到字模工具軟件里,字模軟件會(huì )為每個(gè)字符產(chǎn)生一個(gè)字模數組,我們在程序里按字符顯示的順序依次調用 FontDisplay(int x,int y, unsignedchar * FontModule) 即可連續把字符顯示出來(lái)。記著(zhù)把顯示的偏移位置遞增一個(gè)字符寬度呀( x 或 y)!否則就重疊看不清了。不要笑俺,俺就犯過(guò)如此愚鈍的錯誤!
備注 : putpixel(int x,int y,int color) 函數
x,y為坐標,color為顏色值.該函數在(x,y)點(diǎn)設定象素的顏色.由于硬件的不同,也許提供的函數不同,用戶(hù)可把此函數作為參考,必要時(shí)用硬件提供的函數取而代之。
前面提到的是16x16點(diǎn)陣的字符的顯示方案和程序例程。但往往我們在開(kāi)發(fā)產(chǎn)品的時(shí)候,可能因為產(chǎn)品的體積定位較小,從而需要使用更小的液晶來(lái)顯示;也可能為了顯示更多的字符;還可能為了節約成本,使用較小的存貯器、計算能力一般的廉價(jià)單片機,或者壓根不要存貯芯片,直接把字模數據和程序一起燒在單片機里邊。上述的情況都有可能,解決的最好辦法就是減小點(diǎn)陣的大小,點(diǎn)陣小,自然字模數據就小,存貯、掃描、計算的開(kāi)銷(xiāo)相對也小。但太小的點(diǎn)陣又不容易識別,為此,在漢顯方面,本人根據經(jīng)驗推薦使用12x12點(diǎn)陣。并在此給出一個(gè)12x12點(diǎn)陣的示例,供大家學(xué)習和交流之用。當然,12x12點(diǎn)陣的漢字在LCD和LED顯示屏中是最常用的,其優(yōu)點(diǎn)就不言而喻了。
unsigned char hao0[]={
0x04,0x0, 0xFF,0xE, 0x1F,0x8, 0x10,0x8,
0xFF,0xE, 0x80,0x2, 0x3F,0xC, 0x54,0x8,
0x2B,0x0, 0x12,0x8, 0x6E,0x6, 0x00,0x0
};
unsigned char cmp_w[8]={128,64,32,16,8,4,2,1};
void FontDisplay(int x, int y, unsigned char *FontModule);
void FontDisplay(int x, int y, unsigned char *FontModule)
{/*12x12掃描顯示函數*/
for(int row=0;row<12;row++)
{
for(int c=0;c<8;c++)
if((FontModule[row*2]&cmp_w[c])!=0)
putpixel(c+x,row+y,15);
for(c=0;c<4;c++)
if((FontModule[row*2+1]&cmp_w[c+4])!=0)
putpixel (c+8+x,row+y,15);
}
}
main()
{/*調用顯示主程序*/
FontDisplay(5,5, hao0 );
}
幾種常用的字符動(dòng)態(tài)編碼顯示方案分析
直接固化顯示字模數據: 將要顯示的字符的字模數據通過(guò)字模軟件提取出來(lái),順序燒在存貯器中,當程序要顯示的時(shí)候,直接提取送顯示屏。優(yōu)點(diǎn)是易理解、實(shí)現程序簡(jiǎn)單、空間資源占用少;缺點(diǎn):組織字模數據及尋址比較麻煩,可維護性及靈活性差。針對其缺點(diǎn)并不是沒(méi)有解決的辦法,作者推薦前面提到的漢字字模工具,它可按漢字的拼音批量生成字模數組或匯編 DB表,直接拷貝到程序里即可用,這樣的字模數據可以方便靈活的根據以拼音命名的方式進(jìn)行尋址。用戶(hù)在使用的時(shí)候,直接用漢字的拼音代替字符串中相應的漢字,顯示程序則直接調用該地址的字模數據進(jìn)行顯示。前面在計算機中如何顯示一個(gè)字符中所提到的 C 語(yǔ)言示例就是本方案,靈活方便吧。
創(chuàng )建索引表和點(diǎn)陣字模庫: 索引表包括字符機內碼和該字符在字庫中的偏移地址。如果字符的機內碼的排列順序和字符的字模數據在字庫里的排列順序一致,偏移地址則可通過(guò)計算的方式給出(offset= 該字符機內碼在索引中的位置 No. * 單個(gè)字符的字模數據所占的字節數 bytes ;由本人編寫(xiě)的漢字字模點(diǎn)陣數據批量生成工具 V5.0以上版本可創(chuàng )建機內碼索引表)。在顯示的時(shí)候,先得到字符的機內碼,再得到該字符機內碼在索引中的位置,最后計算出該字符在字庫中的偏移地址并從字庫中取出字模數據進(jìn)行掃描顯示即可。此方法的優(yōu)點(diǎn)是靈活方便,占用空間??;但需要復雜的查詢(xún)、計算、尋址取模等過(guò)程。如果字稍多,單個(gè)字的顯示時(shí)間就會(huì )很長(cháng),會(huì )使系統顯得慢,效率低
創(chuàng )建連續的大字庫: 根據字符編碼,利用字模軟件創(chuàng )建連續的大字庫( Font Model Tool可擔此重任),然后再根據字符編碼直接計算出該字符在字庫中的位置,最后取模顯示。這種方法非常靈活,但是需要計算尋址,因為字庫較大,所以尋址的時(shí)間可能會(huì )較長(cháng),顯示速度較慢。如果你的系統用的是高速芯片(例如: ARM 、 DSP),大容量的存貯器件,這些對你來(lái)說(shuō)不算什么,這種方法最適用你,因為這種方法程序易維護、不需經(jīng)常修改字庫、而且兼容性很強。當然,電子信息發(fā)展到今天,芯片的計算能力已不是什么大的問(wèn)題,越來(lái)越多的存貯芯片不斷推出,價(jià)格低廉,為我們的開(kāi)發(fā)奠定了很好的基礎。同志們,努力吧!展望一下明天,還是很美好的呀!
......要閱讀更多更詳盡的內容,請 下載本文 點(diǎn)擊這里 下載字模軟件工具 符24x24點(diǎn)陣水平掃描C語(yǔ)言示例代碼:
unsigned char mo[]={
0x00,0x00,0x00, 0x00,0x00,0x00, 0x07,0x0C,0xC0, 0x06,0x0C,0xC0,
0x06,0x0C,0xDC, 0x06,0x7F,0xF0, 0x06,0xCC,0xC0, 0x1F,0xF0,0x70,
0x06,0x3F,0xF0, 0x07,0x30,0x70, 0x0F,0xBF,0xF0, 0x0E,0xF0,0x70,
0x1E,0xF0,0x70, 0x1E,0x3F,0xF0, 0x36,0x06,0x18, 0x06,0xFF,0xFC,
0x06,0x07,0x00, 0x06,0x0F,0x80, 0x06,0x0C,0xE0, 0x06,0x38,0x7C,
0x06,0xE0,0x18, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00
};
unsigned char cmp_w[8]={128,64,32,16,8,4,2,1};
void FontDisplay(int x, int y, unsigned char * FontModule)
{
for(int row=0;row<24;row++)
{
for(int c=0;c<8;c++)
if((FontModule[row*3]&cmp_w[c])!=0)
putpixel(c+x,row+y,15);
for(c=0;c<8;c++)
if((FontModule[row*3+1]&cmp_w[c])!=0)
putpixel(c+8+x,row+y,15);
for(c=0;c<8;c++)
if((FontModule[row*3+2]&cmp_w[c])!=0)
putpixel(c+16+x,row+y,15);
}
}
邊框漢顯 一維數組實(shí)現舉例:
unsigned short FontOrg1[]={
/* @中 [Font Model Tool] */
0x00,0x00,0x01,0x00, 0x01,0x00, 0x01,0x08, 0x3F,0xFC, 0x21,0x08, 0x21,0x08,0x21,0x08, 0x21,0x08, 0x3F,0xF8, 0x01,0x00, 0x01,0x00, 0x01,0x00,0x01,0x00, 0x01,0x00, 0x00,0x00};
unsigned short FontOrg2[]={
/* @國 [Font Model Tool] */
0x00,0x00,0x00,0x04, 0x3F,0xFE, 0x20,0x04, 0x2F,0xF4, 0x21,0x04, 0x21,0x04,0x27,0xE4, 0x21,0x44, 0x21,0x24, 0x21,0x04, 0x2F,0xFC, 0x20,0x04,0x3F,0xFC, 0x20,0x04, 0x00,0x00};
unsigned short FontOrg3[]={
/* @移 [Font Model Tool] */
0x00,0x00,0x04,0x20, 0x0E,0x20, 0x38,0x7C, 0x08,0x88, 0x09,0x50, 0x7E,0x20,0x09,0xC0, 0x1C,0x24, 0x2A,0x7E, 0x28,0xC4, 0x4B,0x28, 0x08,0x10,0x08,0x60, 0x0B,0x80, 0x00,0x00};
unsigned short FontOrg4[]={
/* @動(dòng) [Font Model Tool] */
0x00,0x00,0x00,0x20, 0x00,0x20, 0x3E,0x20, 0x00,0x24, 0x00,0xFE, 0x7F,0x24,0x08,0x24, 0x08,0x24, 0x12,0x24, 0x22,0x44, 0x7F,0x44, 0x20,0x84,0x01,0x14, 0x02,0x08, 0x00,0x00};
unsigned short FontEdge1[]={
/* @中 [Font Model Tool] */
0x03,0x80,0x02,0x80, 0x02,0x9C, 0x7E,0xF6, 0x40,0x02, 0x5E,0xF6, 0x52,0x94,0x52,0x94, 0x5E,0xF4, 0x40,0x04, 0x7E,0xFC, 0x02,0x80, 0x02,0x80,0x02,0x80, 0x02,0x80, 0x03,0x80};
unsigned short FontEdge2[]={
/* @國 [Font Model Tool] */
0x00,0x0E,0x7F,0xFB, 0x40,0x01, 0x5F,0xFB, 0x50,0x0A, 0x5E,0xFA, 0x5E,0xFA,0x58,0x1A, 0x5E,0xBA, 0x52,0xDA, 0x5E,0xFA, 0x50,0x02, 0x5F,0xFA,0x40,0x02, 0x5F,0xFA, 0x70,0x0E};
unsigned short FontEdge3[]={
/* @移 [Font Model Tool] */
0x0E,0x70,0x1B,0x50, 0x71,0xDE, 0x47,0x82, 0x77,0x76, 0xF6,0xAC, 0x81,0xD8,0xF6,0x3E, 0x63,0xDB, 0x55,0x81, 0xD7,0x3B, 0xB4,0xD6, 0xF7,0xEC,0x17,0x98, 0x14,0x70, 0x1F,0xC0};
unsigned short FontEdge4[]={
/* @動(dòng) [Font Model Tool] */
0x00,0x70,0x00,0x50, 0x7F,0x50, 0x41,0x5E, 0x7F,0xDB, 0xFF,0x01, 0x80,0xDB,0xF7,0xDA, 0x37,0x5A, 0x6D,0xDA, 0xDD,0xBA, 0x80,0xAA, 0xDF,0x7A,0x76,0xEA, 0x05,0xB6, 0x07,0x1C};
const unsigned short FontProp[][]={
{2,1,12,14}, /* 中 [Font Model Tool]*/
{2,1,13,14}, /* 國 [Font Model Tool]*/
{1,1,14,14}, /* 移 [Font Model Tool]*/
{1,1,14,14} /* 動(dòng) [Font Model Tool]*/
}
main()
{/*調用顯示主程序*/
FontDisplay(8,5, FontOrg1); FontDisplay(8,5, FontEdge1);
FontDisplay(24,5, FontOrg2); FontDisplay(24,5, FontEdge2);
FontDisplay(40,5, FontOrg3); FontDisplay(40,5, FontEdge3);
FontDisplay(56,5, FontOrg4); FontDisplay(56,5, FontEdge4);
}
邊框漢顯 二維數組實(shí)現舉例:
const unsigned short FontOrg[4][32]={
/* @中 [Font Model Tool] */
{0x00,0x00,0x01,0x00, 0x01,0x00, 0x01,0x08, 0x3F,0xFC, 0x21,0x08, 0x21,0x08,0x21,0x08, 0x21,0x08, 0x3F,0xF8, 0x01,0x00, 0x01,0x00, 0x01,0x00,0x01,0x00, 0x01,0x00, 0x00,0x00},
/* @國 [Font Model Tool] */
{0x00,0x00,0x00,0x04, 0x3F,0xFE, 0x20,0x04, 0x2F,0xF4, 0x21,0x04, 0x21,0x04,0x27,0xE4, 0x21,0x44, 0x21,0x24, 0x21,0x04, 0x2F,0xFC, 0x20,0x04,0x3F,0xFC, 0x20,0x04, 0x00,0x00},
/* @移 [Font Model Tool] */
{0x00,0x00,0x04,0x20, 0x0E,0x20, 0x38,0x7C, 0x08,0x88, 0x09,0x50, 0x7E,0x20,0x09,0xC0, 0x1C,0x24, 0x2A,0x7E, 0x28,0xC4, 0x4B,0x28, 0x08,0x10,0x08,0x60, 0x0B,0x80, 0x00,0x00},
/* @動(dòng) [Font Model Tool] */
{0x00,0x00,0x00,0x20, 0x00,0x20, 0x3E,0x20, 0x00,0x24, 0x00,0xFE, 0x7F,0x24,0x08,0x24, 0x08,0x24, 0x12,0x24, 0x22,0x44, 0x7F,0x44, 0x20,0x84,0x01,0x14, 0x02,0x08, 0x00,0x00}
}
const unsigned short FontEdge[4][32]={
/* @中 [Font Model Tool] */
{0x03,0x80,0x02,0x80, 0x02,0x9C, 0x7E,0xF6, 0x40,0x02, 0x5E,0xF6, 0x52,0x94,0x52,0x94, 0x5E,0xF4, 0x40,0x04, 0x7E,0xFC, 0x02,0x80, 0x02,0x80,0x02,0x80, 0x02,0x80, 0x03,0x80},
/* @國 [Font Model Tool] */
{0x00,0x0E,0x7F,0xFB, 0x40,0x01, 0x5F,0xFB, 0x50,0x0A, 0x5E,0xFA, 0x5E,0xFA,0x58,0x1A, 0x5E,0xBA, 0x52,0xDA, 0x5E,0xFA, 0x50,0x02, 0x5F,0xFA,0x40,0x02, 0x5F,0xFA, 0x70,0x0E},
/* @移 [Font Model Tool] */
{0x0E,0x70,0x1B,0x50, 0x71,0xDE, 0x47,0x82, 0x77,0x76, 0xF6,0xAC, 0x81,0xD8,0xF6,0x3E, 0x63,0xDB, 0x55,0x81, 0xD7,0x3B, 0xB4,0xD6, 0xF7,0xEC,0x17,0x98, 0x14,0x70, 0x1F,0xC0},
/* @動(dòng) [Font Model Tool] */
{0x00,0x70,0x00,0x50, 0x7F,0x50, 0x41,0x5E, 0x7F,0xDB, 0xFF,0x01, 0x80,0xDB,0xF7,0xDA, 0x37,0x5A, 0x6D,0xDA, 0xDD,0xBA, 0x80,0xAA, 0xDF,0x7A,0x76,0xEA, 0x05,0xB6, 0x07,0x1C}
}
unsigned char cmp_w[8]={128,64,32,16,8,4,2,1};
void DrawFontOrg(int x, int y, int dim);
void DrawFontEdge(int x, int y, int dim);
void DrawFontOrg(int x, int y, int dim)
{/*16x16掃描顯示函數*/
for(int row=0;row<16;row++)
{
for(int c=0;c<8;c++)
if((FontOrg[dim][row*2]&cmp_w[c])!=0)
putpixel(c+x,row+y,0);/* 畫(huà)一個(gè)點(diǎn) */
for(c=0;c<8;c++)
if((FontModule[dim][row*2+1]&cmp_w[c])!=0)
putpixel(c+8+x,row+y,0);
}
}
void DrawFontEdge(int x, int y, int dim)
{/*16x16掃描顯示函數*/
for(int row=0;row<16;row++)
{
for(int c=0;c<8;c++)
if((FontEdge[dim][row*2]&cmp_w[c])!=0)
putpixel(c+x,row+y,15);/* 畫(huà)一個(gè)點(diǎn) */
for(c=0;c<8;c++)
if((FontEdge[dim][row*2+1]&cmp_w[c])!=0)
putpixel(c+8+x,row+y,15);
}
}
main()
{/*調用顯示主程序*/
DrawFontOrg(8,5,0); DrawFontEdge(8,5,0);
DrawFontOrg(24,5,1); DrawFontEdge(24,5,1);
DrawFontOrg(40,5,2); DrawFontEdge(40,5,2);
DrawFontOrg(56,5,3); DrawFontEdge(56,5,3);
}
所有刊登本文的網(wǎng)站必須經(jīng)作者同意并注明:本文由豪智軟件工具自由職業(yè)者 秦文豪 提供 www.soft-tool.com 字樣
有原意刊登本文的電子報刊或雜志請與本人聯(lián)系!MSN:wenhaoqin@hotmail.com