以 WPF + AJAX 在執行期間將文字轉成 Path

前一篇文章提及將文字用 Expression Blend 轉成 Path, 以避免下載整個 TrueType 字型檔至少 5MB 的負擔。如果我們需要執行時期, 依據使用者的輸入或是資料庫的來源, 就需要借助 ASP.NET AJAX 的幫忙, 由 Server 在執行期間轉成 Path。

但 Blend 是設計師工具, 並不適合用程式去控制, 事實上, Expression Blend 是使用 .NET 3.0 WPF 裡的 API 來作轉換, 同樣的功能在 Expression Design 也可以找得到。只要我們在 IIS 上安裝 .NET 3.0, 經由 WPF + Web Service + AJAX 的合作, 就可以即時將 Silverlight 所需的文字, 轉成任何字型的 Path 格式, 而不需下載整個 TrueType 字型。

ASP.NET 部份:

Reference 加入 PresentationCore 與 WindowsBase

AddReference

加入一個 TextService.asmx 的 Web Service, 記得要有 [ScriptServie] 的宣告, 才能經由 AJAX 呼叫此 Web Service

using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Services;

using System.Windows;
using System.Windows.Media;

namespace SilverlightTextService
{
    /// <summary>
    /// Summary description for TextService
    /// </summary>
    [WebService(Namespace = "https://myuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ScriptService]
    public class TextService : System.Web.Services.WebService
    {

        [WebMethod]
        public string GetTextPath(string str, string fontFamily, int nSize)
        {
            Typeface typeface = new Typeface(new FontFamily(fontFamily),
                FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);

            FormattedText text = new FormattedText(str,
                new System.Globalization.CultureInfo("zh-tw"),
                FlowDirection.LeftToRight, typeface, nSize,
                Brushes.Black);

            Geometry geo = text.BuildGeometry(new Point(0, 0));

            PathGeometry path = geo.GetFlattenedPathGeometry();

            return path.ToString();
        }
    }
}

在 XAML 宣告一個 Path Element, 但不需 Data:

<Path x:Name="textPath" Canvas.Left="29" Canvas.Top="10" Fill="#FFEFEFEF" />

再利用 javascript 呼叫 TextService 以取得 Path:

SilverlightTextService.TextService.GetTextPath("中文顯示", "微軟正黑體", 16, onPathSuccess);

function onPathSuccess(result) {
        scene.rootElement.findName('textPath').Data = result;
}

結果:

result