雖然 silverlight 本身具備極為優越的 2d 向量文字、繪圖與影音能力,但是若缺乏中文字顯示的支援能力,對亞洲國家的使用者、程式設計人員乃至于企業端都會造成很大的困擾,故本文將針對如何讓 silverlight 可以正確顯示中文字型而提供數種解決方案,然而這幾種中文字的顯示方式各有其不同的特性與優缺點,故您可依個案情境,挑選對 silverlight 應用程式及開發成本最佳的方式,所以各位可以視情況而懂得變通,不一定得墨守成規,一個方式用到底。
在此整理一下 silverlight 1.0 用于顯示中文字的幾種解決方案,以下是解決方案架構圖。

圖 3 中文字解決方案架構圖
在上面的架構圖中,我們可以看到顯示中文的途徑有三大類,分別是文字物件、繪圖物件與圖片檔三種,然而這三種方式有著截然不同特性與處理議題,會對您的 silverlight 程式的設計與執行有著顯著的影響,讓我們先來瞭解其個別內容,最后再來針對此三種方案進行初步的比較,中文字解決方案架構圖說明如下:
(一)文字物件
silverlight 用來直接顯示文字的物件有 glyphs 與 textblock,然而此二者有者相當不同的特性,說明如下:
glyphs
glyphs 顯示中文字時,會以非同步的方式從 web 伺服器下載完整的字型檔,但其中最大的困擾是 glyphs 下載整個字型檔會造成網路頻寬的爆增,而過大的下載位元則是 internet 應用程式的殺手之一,同時下載整個字型檔也會涉及字型版權的法律問題。
范例一 使用預設的 glyphs 顯示中文字(完整 ttf 字型檔下載)
本范例將示范如何運用預設的 glyphs 物件來顯示中文字,其最關鍵點在于指定字型檔所在的網路位置給 fonturi 屬性即可。請參考 glyphsttf.html 及 glyphsttf.xaml 程式,以下為 glyphsttf.xaml 程式碼:
glyphsttf.xaml
完成后請執行 glyphsttf.html 程式,執行結果如下圖。
圖 4 glyphs 物件顯示中文字
表面上 glyphs 顯示中文字絲毫不費太多的力氣,但最大的問題在于 glyphs 會下載所有用到的完整字型檔案,一如上面共用到了三個字型檔,所以便會悉數完整下載,這在 silverlight 的程式開發人員電腦上執行時,問題可能不明顯,但若換成錙銖必較 internet 有限頻寬,動輒 5mb 甚至是 10mb 以上的中文字型要下載到 client 端電腦,可能會是網站的致命殺手,故對此問題不可不慎重視之。各位可以到使用者電腦中路徑 c:/documents and settings/adminvista/local settings/temporary internet files/content.ie5/ 目錄下搜尋 *.ttf 檔,便可以找到相關 ttf 檔案。
|||也許冰雪聰明的各位會想到,如果完整的 ttf 檔過大,那是否有可能擷取應用程式所需的部分字型,然后製作一個較小的字型檔,以便字型檔下載時可以較為迅速,如此不就解決了!?答案正是如此,是真的有方法可以只擷取所需的字型,再加以製作成一個 .odttf 檔,而依字型的種類不同,最終檔案的大小可能是幾百 kb~1000kb,至少比起動輒 5mb 或 10mb 以上的 ttf 檔案快多了,在 internet 上傳輸也是一個可行的解決方案。在此筆者先製作出一個標楷體的部分字型檔,其檔案名稱為“3f1838be-604b-601d-da75-b576de686443.odttf”,而各位先只管如何使用這個部分字型檔練習即可,后面會有獨立小節解釋 odttf 字型檔及製作的詳細步驟。
圖 5 glyphs 下載之完整型檔
范例二 使用 glyphs 顯示部分嵌入字型檔 odttf(部分嵌入字型檔下載)
本范例將示范 glyphs 如何使用部分嵌入字型檔 odttf 來顯示中文字型,步驟說明如下:
step 1:製作部分嵌入字型檔 odttf
首先製作名稱為“3f1838be-604b-601d-da75-b576de686443.odttf”的只含部分嵌入字型的檔案,主要是希望縮小字型檔的體積大小,讓 glyphs 可以迅速下載讀取,在這請各位直接使用 odttf 當做練習,先不急著知道怎么製作。
step 2:在 glyphs 指定使用 odttf 字型檔
請在 glyphs 物件的 fonturi 屬性指定 odttf 字型檔所在的完整http網路位置,glyphs 就能夠直接顯示中文字型了,請參考 glyphsodttf.html 及 glyphsodttf.xaml 程式,以下為 glyphsodttf.xaml 程式碼:
glyphsttf.xaml
完成后請執行 glyphsodttf.html 程式,執行結果如下圖。
圖 6 glyphs 顯示部分字型檔
textblock
silverlight 1.0 的 textblock 物件,基本上只能直接顯示英文字型,對于 unicode 字型如中文字則會以小方框替代,不像 glyphs 至少可以顯示中文字型,頂多是字型檔下載稍嫌大了點。而 textblock 不能直接顯示中文的原因,是出在 silverlight 本身沒有內建中文字型,亦不能呼叫作業系統的中文字來使用,再加上 textblock 根本不能像 glyphs 可指定網路上某個位置字型檔的機制,故 textblock 要顯示中文字會較 glyphs 麻煩了點。然而要讓 textblock 顯示中文需要兩個額外步驟:
使用 downloader 物件下載中文字型。
在 textblock 的 setfontsource 方法設定字型檔來源,以及字型檔名稱。
如此便可讓 textblock 可以正常顯示中文字,讓我們來看以下的范例。
范例三 以 downloader 下載完整 ttf 字型供 textblock 使用
本范例將示范如何透過 downloader 物件從 web 伺服器下載所需的完整 ttf 字型到使用者電腦端,如此 textblock 便有中文字型可供顯示中文字,步驟說明如下:
step 1:準備 ttf 中文字型
在此準備一個標楷體的中文字型檔 kaiu.ttf,以及另一個壓縮檔 kaiu.zip,而壓縮或未壓縮的字型檔都可以被 downloader 下載給 textblock 使用,不過想當然爾是壓縮過后的字型下載速度較快,也比較不佔用 internet 頻寬,例如 kaiu.ttf 未壓縮前是 5,015kb,壓縮后是 2,825kb,檔案大小約減少了 43%,下載字型檔的速度當然也更快。
step 2:建立 xaml 程式主體
請參考 textblockdownloaderttf.xaml 的程式主體,以下為 xaml 程式碼:
textblockdownloaderttf.xaml
| 以下是引用片段: <canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" loaded="handleload"> <!-- 進度列指示器 --> <canvas x:name="progressindicator" canvas.left="10" canvas.top="10" canvas.zindex="1"> <rectangle x:name="progressrectangle" canvas.left="10" height="10" width="0" fill="maroon" /> <rectangle canvas.top ="-1" canvas.left="9" height="12" width="202" strokethickness="1" stroke="black" /> <textblock x:name="progresstext" canvas.top ="-4" canvas.left="230" text="0%" fontsize="12" /> </canvas> <canvas name="mycanvas" background="lightblue" width="600" height="400" canvas.top="0" canvas.zindex="0" > <textblock name="mytextblock" textwrapping="wrap" width="300" fontsize="30" canvas.top="80" canvas.left="100" > 千山鳥飛絕 萬徑人蹤滅 孤舟簑笠翁 獨釣寒江雪 </textblock> </canvas> </canvas> |
程式說明:
在 textblock 中指定中文字沒有什么特別的地方,設定方式與英文字相同。
但是有個比較特別的地方是需要額外指定 downloader 的載入程式,而就是在 canvas 或 textblock 的 loaded 事件中指定 javascript 事件,呼叫 downloader 執行非同步的字型檔載入
step 3:建立 downloader 下載程式
請在 textblockdownloaderttf.xaml.js 程式中建立 downloader 相關程式:
textblockdownloaderttf.xaml.js
程式說明:
oncompleted 事件是用來下載字型檔,它是本程式最重要的核心,而 ondownloadprogresschanged 是用來顯示下載進度的百分比,不過是為了人性化,實質上可有可無。完成后請執行 textblockdownloaderttf.html 程式,執行畫面如下圖。
圖 7 textblock 顯示 ttf 完整字型檔
范例四 以 downloader 下載部分嵌入字型檔 odttf 供 textblock 使用
在前面介紹過 glyphs 使用部分嵌入字型檔 odttf,odttf 字型檔的優點是所需的檔案大小可以減少為原來的好幾倍,而 odttf 不止 glyphs 可以使用,同樣的 textblock 也可以使用,只要透過 downloader 下載 odttf 即可,請參考以下的步驟說明:
step 1:製作部分嵌入字型檔 odttf
在此製作一個“01026a73-2351-5325-5665-e8572e1a1805.odttf”的正黑體字型檔,里面所包含的文字為:“千山鳥飛絕,萬徑人蹤滅,孤舟簑笠翁,獨釣寒江雪”,并將其檔壓縮成 embededchinese.zip,借此將 odttf 字型檔由原來的 1,015kb 進一步壓縮到 22kb 而已,這是一個更為驚人的方式,因為可以在 internet 以極高的速度下載傳送。
step 2:建立 xaml 程式主體
請參考 textblockdownloaderodttf.xaml 的程式主體,以下為 xaml 程式碼:
textblockdownloaderodttf.xaml
| 以下是引用片段: <canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <!-- 進度列指示器 --> <canvas x:name="progressindicator" canvas.left="10" canvas.top="10" canvas.zindex="1"> <rectangle x:name="progressrectangle" canvas.left="10" height="10" width="0" fill="maroon" /> <rectangle canvas.top ="-1" canvas.left="9" height="12" width="202" strokethickness="1" stroke="black" /> <textblock x:name="progresstext" canvas.top ="-4" canvas.left="230" text="0%" fontsize="12" /> </canvas> <canvas name="mycanvas" background="lightblue" width="600" height="400" canvas.top="0" canvas.zindex="0" > <textblock name="mytextblock" textwrapping="nowrap" width="300" fontsize="30" canvas.top="100" canvas.left="100" loaded="handleload"> 千山鳥飛絕 萬徑人蹤滅 孤舟簑笠翁 獨釣寒江雪 <textblock.rendertransform> <rotatetransform angle="30" centerx="150" centery="150"/> </textblock.rendertransform> </textblock> </canvas> </canvas> |
step 3:建立 downloader 下載程式
請在 textblockdownloaderodttf.xaml.js 程式中建立 downloader 相關程式:
textblockdownloaderodttf.xaml.js
程式說明:
正黑體字型的英文名稱為“microsoft jhenghei”,在程式中指定正黑體時必須使用英文名稱而非中文名稱。完成后請執行 textblockdownloaderodttf.html 程式,執行畫面如下圖。
圖 8 textblock 顯示部分嵌入 odttf 字型檔
警告:
odttf 檔的名稱不可以任意做更改,否則便無法作用。
若要使用到的中文字都必須事先出現在 odttf 檔之中,不可以臨時使用未曾事先輸入的中文字
odttf 字型檔除了事先製作外,也可以動態產生,請參考另一位微軟專家黃忠誠之專欄文章“silverlight 完全中文解決方案”,網址如下:
http://www.microsoft.com/taiwan/msdn/columns/huang_jhong_cheng/silverlight_cht_solutions.htm
|||(二)path 向量繪圖物件
將中文字型轉換成 path 向量繪圖物件,其原理是將中文字轉換成大量的繪圖座標資訊,并且透過 path 幾何繪圖物件來顯示這些座標資料。但是使用這個方法有一點要特別注意,一旦將文字轉換成 path 物件之后,它就是圖形,無論它是不是向量與否,它已不再是文字了,因此不能被檢索查詢,也不能以字串的型式存入資料庫,更不可被 search engine 搜尋引擎所爬文檢索。故倘若您的網站很在意是否能被搜尋引擎爬文檢索,進而影響您的網站或商品在搜尋引擎網站可以被使用者或顧客查詢到,就要特別意識到避免使用這個方法。
然而將中文字型轉換成 path 向量繪圖物件有兩個簡單的基本型式,第一是使用像 expression blend 2 這類的工具將文字轉換成 path 物件,第二個方式是撰寫一個 web services,透過程式呼叫 web services 將轉換后的 path 物件回傳給 silverlight 應用程式。
圖 9 中文字型轉換成 path 向量圖形
范例五 使用 blend 2 將中文字型轉換成 path 向量繪圖物件
本范例將示范使用 blend 2 將中文字型轉換成 path 向量繪圖物件,步驟說明如下:|||
step 1:開啟 blend 2 輸入中文字
首先您必須下載并安裝 expression blend 2 開發工具,并在其中以 textblock 物件輸入中文字,例如:“月落烏啼霜滿天”的中文字。
step 2:將 textblock 文字轉換成 path 向量圖形
首先點選 textblock 文字物件,并點選【object】選單 ->【path】->【convert to path】,如此便能將 textblock 中文字轉換成 path 向量圖形。
圖 10 blend2 將中文字轉換成 path 向量圖形
這個方法雖然可以將“月落烏啼霜滿天”七個中文字轉換成 path 向量座標的資訊描述,但是其結果卻是巨幅的84行復雜的描述資料,而這種方式好或不好各位可以自己評估。
圖 11 巨量的 path 物件座標描述資料
相對于事先用 blend 2 將中文字轉換成 path 向量圖形,那還有另一種可以透過事先撰寫好的 web services,讓它回傳中文的 path 向量圖形,一來免除了 blend 2 工具的需求,二來可以動態產生。可是其缺點是您必須維護一臺 web services 的伺服器,但如果您是將 silverlight 應用程式伺服器放在 linux 作業系統上的 web server,這時又該如何?是另外找一臺 windows 主機來建立 web services 服務?這也是有點莞爾的,故動態呼叫 web services 就有這樣子的缺點存在。
注:
至于動態產生 path 向量中文圖形,請參考微軟專家周旺暾的一篇文章“以 wpf + ajax 在執行期間將文字轉成 path”,其網址為:
http://blogs.msdn.com/wtchou/archive/2007/08/13/wpf-ajax-path-silverlight.aspx
新聞熱點
疑難解答