论坛首页· 友情链接申请·申请版主· 广告投放· 道具中心· 设为首页· 收藏本站
发新话题
打印

Silverlight 1.0 中文字显示

本主题由 Webmaster 于 2008-8-30 00:49 移动

Silverlight 1.0 中文字显示

虽然 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
以下是引用片段:
    
<Canvas xmlns="http://schemas.microsoft.com/client/2007"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
    <Canvas Name="myCanvas" Background="LightBlue" Width="600"
        Height="400" MouseLeftButt>
        <!--Glyphs1-->
        <Glyphs
          F
          F
          UnicodeString       = "Silverlight"
          Fill                = "Black"
          OriginX             = "0"
          OriginY             = "100">
        </Glyphs>
        <!--Glyphs2-->
        <Glyphs
           F
           F
           UnicodeString       = "正黑體"
           Fill                = "Red"
           OriginX             = "0"
           OriginY             = "200"
           >
        </Glyphs>
        <!--Glyphs3-->
        <Glyphs
           F
           F
           UnicodeString       = "楷書體"
           Fill                = "Black"
           OriginX             = "0"
           OriginY             = "300">
        </Glyphs>
    </Canvas>
</Canvas>
  完成后请执行 GlyphsTTF.html 程式,执行结果如下图。

  图 4 Glyphs 物件显示中文字

  表面上 Glyphs 显示中文字丝毫不费太多的力气,但最大的问题在于 Glyphs会下载所有用到的完整字型档案,一如上面共用到了三个字型档,所以便会悉数完整下载,这在 Silverlight的程式开发人员电脑上执行时,问题可能不明显,但若换成錙銖必较 Internet 有限频宽,动輒 5MB 甚至是 10MB以上的中文字型要下载到 Client 端电脑,可能会是网站的致命杀手,故对此问题不可不慎重视之。各位可以到使用者电脑中路径C:\Documents and Settings\adminvista\Local Settings\Temporary InternetFiles\Content.IE5\ 目录下搜寻 *.ttf 档,便可以找到相关 ttf 档案。
回帖既是一种美德,是对作者的鼓励,同时又为后来者推荐了好文章,何乐而不为呢?

TOP

silverlight

也许冰雪聪明的各位会想到,如果完整的 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
<CANVAS
以下是引用片段:
<Canvas
  xmlns="http://schemas.microsoft.com/client/2007"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Canvas >
        <Glyphs Fill="Blue" UnicodeString="春花秋月何時了,"
    F
          F Canvas.Top="0"/>
        <Glyphs Fill="Blue" UnicodeString="往事知多少,"
    F
          F Canvas.Top="40"/>
        <Glyphs Fill="Red" UnicodeString="小樓昨夜又東風,"
    F
        F Canvas.Top="80"/>
        <Glyphs Fill="Red" UnicodeString="故國不堪回首月明中"
    F
        F Canvas.Top="120"/>
    </Canvas>
</Canvas>
  完成后请执行 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" p
以下是引用片段:
<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%" F />
    </Canvas>
     
    <Canvas Name="myCanvas" Background="LightBlue" Width="600"
         Height="400" Canvas.Top="0"  Canvas.ZIndex="0" >
        <TextBlock Name="myTextBlock"  
            TextWrapping="Wrap"  Width="300" F  
            Canvas.Top="80" Canvas.Left="100" >
            千山鳥飛絕
            萬徑人蹤滅
            孤舟簑笠翁
            獨釣寒江雪
</TextBlock>
    </Canvas>
</Canvas>
回帖既是一种美德,是对作者的鼓励,同时又为后来者推荐了好文章,何乐而不为呢?

TOP

程式说明:  在 TextBlock 中指定中文字没有什么特别的地方,设定方式与英文字相同。
  但是有个比较特别的地方是需要额外指定 Downloader 的载入程式,而就是在 Canvas 或 TextBlock 的 Loaded 事件中指定 JavaScript 事件,呼叫 Downloader 执行非同步的字型档载入
  Step 3:建立 Downloader 下载程式
  请在 TextBlockDownloaderTTF.xaml.js 程式中建立 Downloader 相关程式:
  TextBlockDownloaderTTF.xaml.js
以下是引用片段:
  var delegate1;
  var delegate2;
  // Loaded 事件处理常式。
  function handleLoad(sender, eventArgs)
  {
  // 取得Silverlight Plugin物件
  var slPlugin = sender.getHost();
  // 建立Downloader 物件
  var downloader = slPlugin.createObject("downloader");
  // 建立DownloadProgressChanged与Completed 事件委派
  delegate1= downloader.addEventListener("downloadProgressChanged", onDownloadProgressChanged);
  delegate2= downloader.addEventListener("completed", onCompleted);
  // 初始化下载要求
  downloader.open("GET", "Fonts/Kaiu.zip");
  //下载未压缩的TTF字型也可以
  //downloader.open("GET", "Fonts/Kaiu.ttf");
  // 开始传送下载
  downloader.send();
  }
  // Completed 事件处理常式
  function onCompleted(sender, eventArgs)
  {
  // 移除DownloadProgressChanged 事件与其事件处理常式的委派关係
  sender.removeEventListener("downloadProgressChanged", delegate1);
  // 移除Completed 事件与其事件处理常式的委派关係
  sender.removeEventListener("completed", delegate2);
  var textblock = sender.findName("myTextBlock");
  textblock.setFontSource(sender);
  textblock.f;
  //将Downloader物件设定为null
  sender = null;
  }
  // 负责更新进度列
  function onDownloadProgressChanged(sender, eventArgs)
  {
  var progressText = sender.findName("progressText");
  var progressRectangle = sender.findName("progressRectangle");
  // 计算下载的百分比
  var percentage = Math.floor(sender.downloadProgress * 100);
  // 更新进度列的Rectangle 与TextBlock 物件
  progressText.text = percentage + "%";
  progressRectangle.width = percentage * 2;
  }

  程式说明:
  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" p 以下是引用片段:
<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%" F />
    </Canvas>
     
    <Canvas Name="myCanvas" Background="LightBlue" Width="600"  
       Height="400" Canvas.Top="0"  Canvas.ZIndex="0" >
          <TextBlock Name="myTextBlock"  
            TextWrapping="NoWrap"  Width="300" F  
            Canvas.Top="100" Canvas.Left="100" Loaded="handleLoad">
            千山鳥飛絕
            萬徑人蹤滅
            孤舟簑笠翁
            獨釣寒江雪
            <TextBlock.RenderTransform>
                <RotateTransform Angle="30" CenterX="150"
                  CenterY="150"/>
            </TextBlock.RenderTransform>
        </TextBlock>
    </Canvas>
</Canvas>
回帖既是一种美德,是对作者的鼓励,同时又为后来者推荐了好文章,何乐而不为呢?

TOP

Step 3:建立 Downloader 下载程式  请在 TextBlockDownloaderODTTF.xaml.js 程式中建立 Downloader 相关程式:
  TextBlockDownloaderODTTF.xaml.js
以下是引用片段:
  var delegate1;
  var delegate2;
  // Loaded 事件的事件处理常式
  function handleLoad(sender, eventArgs)
  {
  // 取得Silverlight Plugin的参考。
  var slPlugin = sender.getHost();
  // 建立Downloader 物件
  var downloader = slPlugin.createObject("downloader");
  // 建立DownloadProgressChanged 与Completed 事件委派。
  delegate1 = downloader.addEventListener("downloadProgressChanged",
  onDownloadProgressChanged);
  delegate2 = downloader.addEventListener("completed", onCompleted);
  // 初始化下载要求
  downloader.open("GET", "Fonts/EmbededChinese.zip");
  // 开始传送下载
  downloader.send();
  }
  // Completed 事件处理常式
  function onCompleted(sender, eventArgs)
  {
  // 取消DownloadProgressChanged 事件与其事件处理常式的委派关係
  sender.removeEventListener("downloadProgressChanged", delegate1);
  // 取消Completed 事件与其事件处理常式的委派关係。
  sender.removeEventListener("completed", delegate2);
  var textblock = sender.findName("myTextBlock");
  textblock.setFontSource(sender);
  textblock.TextWrapping="Wrap";
  textblock.f;
  // 将Downloader 物件设定成null
  sender = null;
  }
  // 负责更新进度列
  function onDownloadProgressChanged(sender, eventArgs)
  {
  var progressText = sender.findName("progressText");
  var progressRectangle = sender.findName("progressRectangle");
  // 计算下载的百分比
  var percentage = Math.floor(sender.downloadProgress * 100);
  // 更新进度列的Rectangle 与TextBlock 物件
  progressText.text = percentage + "%";
  progressRectangle.width = percentage * 2;
  }

  程式说明:
  正黑体字型的英文名称为“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物件之后,它就是图形,无论它是不是向量与否,它已不再是文字了,因此不能被检索查询,也不能以字串的型式存入资料库,更不可被 SearchEngine搜寻引擎所爬文检索。故倘若您的网站很在意是否能被搜寻引擎爬文检索,进而影响您的网站或商品在搜寻引擎网站可以被使用者或顾客查询到,就要特别意识到避免使用这个方法。
  然而将中文字型转换成 Path 向量绘图物件有两个简单的基本型式,第一是使用像 Expression Blend2 这类的工具将文字转换成 Path 物件,第二个方式是撰写一个 Web Services,透过程式呼叫 Web Services 将转换后的Path 物件回传给 Silverlight 应用程式。

图 9 中文字型转换成 Path 向量图形

  范例五 使用 Blend 2 将中文字型转换成 Path 向量绘图物件
  本范例将示范使用 Blend 2 将中文字型转换成 Path 向量绘图物件,步骤说明如下:
回帖既是一种美德,是对作者的鼓励,同时又为后来者推荐了好文章,何乐而不为呢?

TOP

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 就有这样子的缺点存在。
回帖既是一种美德,是对作者的鼓励,同时又为后来者推荐了好文章,何乐而不为呢?

TOP

发新话题