Latin Script,軟件開發者中使用最爲普遍的script,同時也是在顯示的時候最不復雜的script,特別是當用它來書寫英語的時候。使用Latin Script,他們的字符能夠被從左至右順序顯示,就像這些字符在內存中存儲的順序同樣。有些scripts則須要一些比Latin script更爲複雜的渲染的過程。咱們把這些scripts稱爲「複雜scripts」,把用這些scripts書寫的文本稱爲「複雜文本」。複雜scripts的例子有Indic scripts(好比,Devanagari,Tamil,Telugu 和Gujarati),Thai,和阿拉伯。 html
這些複雜scripts展現了Latin script所未曾有的複雜化。下面會列出複雜文本的主要的複雜化: 編程
ICU LayoutEngine就是設計用來經過一個簡單的一致的客戶端接口來處理這些複雜化。客戶端以讀取或「邏輯」的順序提供Unicode 代碼點(Unicode的字符被稱爲代碼點),而後LayoutEngine以正確的順序,提供須要顯示的字形及各個字形的位置信息。 數組
因爲ICU LayoutEngine是平臺獨立的,而文本渲染則固有的依賴於平臺,於是LayoutEngine不能直接顯示文本。它使用一個抽象的基類來訪問字庫文件。這個基類建模了某一特定點大小及設備解析度下的TrueType字庫。TrueType字庫有以下的這樣一些特性: app
因爲複雜文本顯示的許多上下文形式,練字,切分開的字符等沒有Unicode代碼點,於是他們就只能被他們的glyph 索引來指代。於是,LayoutEngine的輸出是一個glyph 索引的列表。這意味着輸出必須用一個接口來顯示,在這個接口中,字符有glyph 索引來講明,而不是代碼點。 ide
必須爲每個目標平臺都寫一個這種基類的具體實例。一個簡單的使用標準C庫訪問TrueType字庫文件的例子,能夠在 icu/source/test/letest看PortableFontInstance類。 測試
ICU LayoutEngine以以下的方式支持複雜文本: ui
OpenType處理過程在使用OpenType 表以前,,須要先完成某個script的特定處理。ICU LayoutEngine爲Arabic,Devanagari,Bengali,Gurmukhi,Gujarati,Oriya,Tamil,Telegu,Kannada,和Malayalam文本執行這個處理。 spa
因爲它只在自左向右文本中應用默認的features,因此LayoutEngine中的AAT處理則相對簡單。這個處理已經爲Devanagari文本作過測試。因爲AAT處理不是特定script的,它對其餘scripts可能不起做用。 設計
ICU LayoutEngine 被設計出來用於處理一段文本,這段文本的全部glyph能夠在相同的一個字庫文件裏面找到。這段文字具備一致的方向(自左向右或自右向左),同時具備相同的script。客戶端能夠使用ICU的Bidi 處理來肯定文本的方向,並使用icu/source/extra/scrptrun中的ScriptRun類來查找具備相同script的一段文本。因爲字庫文件信息的表示方法因應用而已,ICU沒法協助查找這些文本段。 代碼規範
一旦文本已經被切分紅了LayoutEngine能夠處理的文本片斷,則能夠調用LayoutEngineFactory來建立一個特定於文本的LayoutEngine類的實例。下面的code演示了一個對於LayoutEngineFactory的調用:
LEFontInstace *font = <the text's font>; UScriptCode script = <the text's script>; LEErrorCode error = LE_NO_ERROR; LayoutEngine *engine; engine = LayoutEngine::layoutEngineFactory(font, script, 0, // language - ignored error); |
下面的例子展現瞭如何使用LayoutEngine來處理文本:
LEUnicode text[] = <the text to process>; le_int32 offset = <the starting offset of the text to process>; le_int32 count = <the number of code points to process>; le_int32 max = <the total number of characters in text>; le_bool rtl = <true if the text is right-to-left, false otherwise>; float x, y = <starting x, y position of the text>; le_int32 glyphCount; glyphCount = engine->layoutChars(text, offset, count, max, rtl, x, y, error); |
前面的例子計算了三個數組:一個以顯示順序呈現的glyph索引的數組,一個每一個glyph對應其中一個元素的(x,y)位置對的數組,和一個將輸出的glyph映射回輸入文本數組的數組。使用下面的get 方法來拷貝這些數組:
LEGlyphID *glyphs = new LEGlyphID[glyphCount]; le_int32 *indices = new le_int32[glyphCount]; float *positions = new float[(glyphCount * 2) + 2]; engine->getGlyphs(glyphs, error); engine->getCharIndices(indices, error); engine->getGlyphPositions(positions, error); |
|
|
位置數組包含(glyphCount * 2) + 2項。這是因爲每一個glyph有一個x和一個y位置。額外的兩個位置保存文本段末尾的x,y位置。 |
一旦用戶獲取了glyph 索引和位置,他們就能夠使用特定於平臺的code來畫出glyphs了。好比,在Windows 2000上,用戶能夠用ETO_GLYPH_INDEX選項來調用ExtTextOut以畫出glyph,而在Linux平臺上,用戶則能夠調用 FT_Load_Glyph來獲取每個glyph的bitmap。然而,用戶必須本身畫出bitmaps。
ICU LayoutEngine是與ICU的其餘部分分開開發的,於是它使用了不一樣的代碼規範和基本類型。爲了以ICU 代碼規範來使用LayoutEngine,用戶能夠使用ICULayoutEngine類,這是LayoutEngine類的一個檢點包裝,並且它符合ICU conventions和基本類型。 |
關於如何調用LayoutEngine更詳細的例子,能夠參考 icu/source/test/letest/letest.cpp。這是一個簡單的用於驗證LayoutEngine是否正常工做的一個測試。它沒有作任何的複雜文本的渲染。
更多詳情,請參考 ICU,OpenType Specification和TrueType Font File Specification。