字库字符编码
無辜的“聯通”:
???????在windows下打開一個記事本,輸入“聯通”保存后,再次打開卻發現“聯通”不見了
???????首先了解,不同編碼文本的存儲,開頭字節:
??UTF-8:???????????????????????????????????EF?BB?BF
??UTF-16/UCS-2,little?endian:?FF?FE?
??UTF-16/UCS-2,big?endian:????FE?FF?
??UTF-32/UCS-4,little?endian:??FF?FE?00?00
??UTF-32/UCS-4,big?endian:????00?00?FE?FF
???????“連通”的幾種編碼:
??GBK:????????????????????????C1?AA?CD?A8
??UTF-16(big?endian):DE?8F?1A?90?
??UTF-8:?????????????????????E8?BF?9E?E9?80?9A
打開一個文本要確定它的編碼格式有三種途徑:?
???????第一:檢測文本開頭字節(最理想的方法)
???????第二:猜測,通過讀取幾個字符測試出可能的編碼類型(防止未加格式頭)
???????第三:提示,當打開一個不確定編碼類型的文本時可以彈出對話框,讓用戶來選擇(如mail)
???????其實軟件開發中可能三種方法都會用到
???????Microsoft在采用第二種方法進行打時出錯
???????“聯通”的錯誤出在TXT文件在保存時默認采用ANSI,而當打開時自動猜測成UTF-8打開
???????所以顯示亂碼,是猜錯引起的。而只要我們以保存的編碼方式打開就不會出問題。而“聯通”這個編碼是個意外
?
從字符編碼角度分析原因:?
???????這應該就是Microsoft程序上的bug了,且至今未找到更好的解決方案(做了優化,即可能是隨機多取幾字符進行測試?,所以在“聯通”后面如果再多輸入幾個字符就不會出現亂碼了)
???????先看“聯通”的內碼(GBK):0xC1AACDA8
??C1-?1100?0001?
??AA-?1010?1010?
??CD-?1100?1101?
??A8-?1010?1000?
???????其中一二字節和三四字節中開頭都是“110”和“10”,正好與UTF8規則里的雙字節模板一致,所以就猜成按UTF-8編碼方式打開了
???????所以只要出現類似“110”和“10”的字符編碼,且以ANSI存儲,自動打開都會出現亂碼的情況,如“聯系”和“this?app?can?break”?等等
???????根據規則統計,一切字符的高字節在C0≤AA≤DF且低字節在80≤BB≤BF這個范圍時,notepad都無法確認文檔的格式,沒有自動依照ANSI格式來顯示
???????而“聯通”就是0xC1AACDA8,剛好在上面地范圍內,所以不能正常顯示,像這樣的字符有近二千個
???????所以說“聯通”是無辜的
?
字庫:
???????是外文字體、中文字體以及相關字符形狀的電子文字字體集合,被廣泛用于計算機、網絡及相關電子產品上
字庫分類:?
???????按語種不同可分為:外文字庫、中文字庫、圖形符號庫;外文字庫又可分為:英文字庫、俄文字庫、日文字庫等等
???????按不同公司劃分為:微軟字庫、方正字庫、漢儀字庫、文鼎字庫、漢鼎字庫、長城字庫、金梅字庫等等
???????按歷史版本劃分,如漢字庫:GB字庫、GBK字庫、GB18030字庫等等
???????按字符字形劃分如:宋體、楷體、方正舒體、黑體、MingLiU、Gulim等
???????按字模存在形式劃分為,常見的有:點陣字庫、矢量字庫、PostScript字庫、圖形字庫等
?
以GB2312字庫舉例說明:?
???????為了便于管理GB2312字庫,通常采用的是區位碼(內碼–?0xA0A0)進行檢索?
???????假設:有一字符串str,當前字號占s_size字節,求當前字符在字庫中的偏移地址offset_addr
?s_row?=?*(str)-0xA0;?
?s_col?=?*(str+1)-0xA0;?
?offset_addr=(94*(s_row-1)+(s_col-1))*s_size;
?
???????讀取點陣信息到buffer:
?fseek(fp,offset_addr,SEEK_SET);?
?fread(buffer,s_size,1,fp);?
?
6、矢量字體的應用移植:
???????FreeType?2被設計為一種占用空間小、高效、高度可定制的、并且可以產生可移植的高品質輸出(符號圖像)。可以被用在諸如圖像庫、展出服務器、字體轉換工具、圖像文字產生工具等多種其它產品上
???????FreeType?2的發行遵循兩個開源許可:BSD樣式的FreeType?License和GPL
???????它提供一個簡單的、易用的并且統一的接口實現對多種字體文件的訪問
???????盡管點陣字體在時間和空間性能上都有較佳的表現,但是由于缺乏靈活性,不便于改變字體的大小和風格
???????矢量字體不像點陣字體那樣直接記錄字符的字模數據,而是記錄字體描述信息,其中最重要的兩部分是outline和hint
???????outline(輪廓):這是用來描述字體的基本手段,它一般由直線和貝塞爾曲線組成。貝塞爾曲線是一條由三個點確定的曲線,假設這三點的坐標是(Ax,Ay)、(Bx,?By)?和(Cx,?Cy),那么曲線方程為:?
????px?=?(1-t)2.Ax?+?2t(1-t).Bx?+?t2.Cx
????py?=?(1-t)2.Ay?+?2t(1-t).By?+?t2.Cy
???????hint(精調):Outline已經描述字體的表現形式,但是數學上的正確對人眼來說并不見得合適,特別是縮放到特定的大小和分辨率的時候,字體可能變得不好看,或者不清析。hint指的是一系列的技術,用來微調字體,讓字體變得更美觀,更清析
???????字符影射表(charmap):字符對應的字體數據稱為glyph,字體文件中通常帶有一個字符映射表,用來把字符映射到對應glyph的索引值
???????矢量字體有多種不同的格式,其中TrueType用得最為廣泛,它的擴展名通常為OTF或者TTF
???????它的文件內容由幾部分組成,文件頭、表目錄和表。文件頭描述了版本號和表的數目等信息,表目錄記錄了表的偏移量和大小,表則是文件的實際數據
???????矢量字體的處理比較麻煩,即要進行矢量計算,又要進行精調處理,相對于點陣字體處理要慢
?
freetype2應用移植:?
freetype-2.1.10下載地址:
http://iask.sina.com.cn/u/2487717952/ish
或http://savannah.nongnu.org/download/freetype/
編譯配置:?
???????./configure?--host=arm-linux?--prefix=/xxx/xxx
???????make
???????make?install
?
應用程序的編寫:
常用頭文件包含:?
???????#include?<ft2build.h>
???????#include?<freetype/freetype.h>
???????#include?<freetype/fttrigon.h>
???????#include?<freetype/ftstroke.h>
應用程序編譯:?
??export???C_INCLUDE_PATH=/home/xiuhai/Desktop/libfree/include/:/home/xiuhai/Desktop/libfree/include/freetype2/
??arm-linux-gcc?-L/home/xiuhai/Desktop/libfree/lib/?-lfreetype?-o?t?freetype_test.c
運行時要拷貝動態庫到開發板lib下,TTY字體庫可以拷貝到應用程序指定的位置
當新建一個face對象時,freetype2默認選擇Unicode字符表
初始化freetype:?
???????FT_Library??library;
???????FT_Init_FreeType(?&library?);
加載字體創建face:?
???????FT_Face?face;
???????FT_New_Face(library,"simfang.ttf",0,?&face)
設置字體大小(寬/高):?
???????FT_Set_Pixel_Sizes(face,?16,0)
根據目標編碼獲取字符在字庫中的索引:?
???????FT_UInt?glyph_index;
???????glyph_index?=?FT_Get_Char_Index(face,unicode);
按指定的大小加載字符的glyph:?
???????FT_Load_Glyph(face,glyph_index,FT_LOAD_DEFAULT)
將指定的glyph轉換成bitmap:?
???????FT_Render_Glyph(face->glyph,FT_RENDER_MODE_MONO)
?
FT_GlyphSlot結構體部分成員信息:?
??bitmap_left:距離左邊的空余像素
??bitmap_top:?用于描述頂部空白區???(bitmap.rows?-?bitmap_top)?
??bitmap.rows:字符所占的行數
??bitmap.width:字符所占的列數
??bitmap.pitch:絕對值表示一行所占字節數
??bitmap.pixel_mode:像素模式,1指單色的,8表示反走樣灰度值
??bitmap.buffer:glyph的點陣位圖內存綬沖區
?
????????????????????????源碼實例(用到的字庫可以到C:\WINDOWS\Fonts去拷貝)
?
Freetype2其他應用:?
指定字符編碼集:?
???????FT_Select_Charmap(face,?FT_ENCODING_GB2312);
字形變換:?
???????仿射、旋轉、文字渲染、縮放、自居調整等?
?
7、多國語言開發:
?
對于一個嵌入式產品多語言支持,一般分兩部分:?
???????一是終端本地顯示界面,如菜單、圖標等
???????二是來自外部的文件,需要在終端上進行顯示
針對上面兩點,都離不開Codepage與Unicode,同時還要有支持各國語言的內碼表及各國語言內碼所對應的字庫或Unicode字庫
???????開發工作主要集中在編碼轉換和字庫索引這塊,編碼轉換方式多樣,效率也會不同
對于字符顯示的方案:?
???????對于本地字符串顯示,由于內容比較少,可以將字符串定義在頭文件中,為了便于隨時修改,也可以做成XML文件
???????字符串可以是文本也可以是內碼(字符串內碼數組)
???????可以采用各國內碼字庫,不過得熟悉其編碼規則,所以不怎么采用
???????一般采用Unicode字庫,或TTY字庫
???????Freetype2為多國語顯示提供了很大方便,我們只需要傭用相應語言的TTY字庫就可以方便的顯示字符了
轉自: http://blog.sina.com.cn/s/blog_94479040010159sq.html
總結
- 上一篇: 打字心得
- 下一篇: 一位程序员的独白:尽管我一生坎坷,但我仍